Encryption finding · Edge
Incomplete Certificate Chain: Fix It or Document It
Your scanner flagged an incomplete certificate chain or missing intermediate. What it means, how to serve the full chain, and how to document what can't change.
What the scanner said
Incomplete certificate chainChain issues: incompleteMissing intermediate certificateYour server presents its own certificate but not the intermediate certificate that links it to a trusted root. SSL Labs reports it as Chain issues: Incomplete, and Nessus often raises it as SSL Certificate Cannot Be Trusted (plugin 51192). Some clients rebuild the chain themselves and connect anyway. Others fail the connection, which is why the site can work in a browser and break in an API client or device.
Why it matters
A missing intermediate is a trust and availability problem. Clients that cannot rebuild the chain refuse the connection, and teams under pressure sometimes respond by switching certificate verification off in the client, which is a real security regression.
PCI DSS 4.2.1 requires the certificates that protect cardholder data over open, public networks to be confirmed valid, and a chain that clients cannot validate undercuts that. NIST 800-53 IA-5(2) expects clients to build a certification path to a trust anchor.
The fix
Serve the full chain: your certificate first, then each intermediate in issuing order, and no root.
# build the file, leaf first, then confirm it holds two or more certificates
cat leaf.pem intermediate.pem > fullchain.pem
grep -c "BEGIN CERTIFICATE" fullchain.pem
# nginx
ssl_certificate /etc/ssl/fullchain.pem;
# Apache 2.4.8 or later (SSLCertificateChainFile is obsolete from 2.4.8)
SSLCertificateFile /etc/ssl/fullchain.pem
# Apache before 2.4.8
SSLCertificateFile /etc/ssl/leaf.pem
SSLCertificateChainFile /etc/ssl/intermediate.pem
# HAProxy: one combined PEM holding the leaf, the intermediates, and the server key
bind :443 ssl crt /etc/haproxy/site.pemIf a PEM file has no trailing newline, cat fuses its END line into the next BEGIN line and breaks the file, which is why the count check matters. On Windows Server (IIS), import the intermediate into the Local Computer store under Intermediate Certification Authorities, then remove and re-add the site's HTTPS binding. For Tomcat and other Java servers, import the full chain into the keystore entry for the server certificate. On a managed load balancer or CDN, upload the certificate with the CA's full-chain or bundle file, or use the platform's managed certificate option. Test whatever actually terminates TLS: if a load balancer sits in front, the fix belongs there.
Verify. List what the server actually sends.
openssl s_client -connect <host>:443 -servername <host> -showcerts </dev/nullThe -servername flag matters on shared hosts, which serve a different certificate without it. A fixed host lists your certificate (0 s:) and its intermediate or intermediates (1 s: and up) under Certificate chain and ends with Verify return code: 0 (ok). A host with a missing intermediate lists only its own certificate and returns 21 (unable to verify the first certificate). Rerun your scanner too, and keep the before and after output as the evidence that the finding is closed.
When you can't fix it
Sometimes the chain is not yours to change: a vendor-hosted endpoint, or an appliance whose certificate screen accepts only a single certificate. Your named owner chooses one treatment.
- Remediate by asking the vendor for a fix or a firmware update, or by moving the endpoint behind a load balancer or proxy you control.
- Mitigate by installing the missing intermediate in the trust store of the clients you manage, so they can validate the chain without help. This covers your own fleet and leaves outside clients unfixed, and it breaks quietly when the CA rotates its intermediate, so put the renewal on the review calendar.
- Accept with documented compensating controls: the endpoint, why the chain can't change, who the affected clients are, the owner, a review date, and the vendor's fix date. For an external scan, give the scanner's vendor that record. The reviewer decides.
The post Compensating Controls for Legacy Systems covers which controls carry weight and how to write the record an assessor accepts.
Where it lands in the Risk Register
| Finding | Treatment | Owner | Evidence |
|---|---|---|---|
| Incomplete certificate chain on a named endpoint | Remediate, mitigate, or accept (the owner decides) | Named by you | openssl output showing the full chain and a return code of 0. Maps to PCI DSS 4.2.1 and NIST 800-53 SC-8 and IA-5(2), with SC-17 for trust anchors. |
Common questions
Why does my site work in a browser but fail in curl or an app?
Chrome, Edge, and Safari download a missing intermediate on their own, and Firefox ships a preloaded list of intermediates. Command-line tools, Java, Python, and many API clients and devices do neither, so they fail with errors such as curl's "unable to get local issuer certificate" (error 60), Java's "PKIX path building failed", or Python's CERTIFICATE_VERIFY_FAILED.
Should the chain file include the root certificate?
Leave it out. TLS lets the server omit the root because clients already hold it, and sending it only adds bytes to every handshake. Send your certificate first, then each intermediate in order.
Do I need a new certificate to fix this?
No. The certificate is fine. Only the file the server presents changes, so the fix does not touch the key or the issuance. Use the intermediate that issued this certificate: CAs rotate intermediates, so take the bundle that came with it.
SSL Labs says my grade is capped at B. Is this why?
It can be. When the chain is incomplete, SSL Labs reports that the certificate chain is incomplete and caps the grade at B. Fix the chain, then clear the SSL Labs cache before you retest.
Related reading
Need the finding closed, or documented so it stays open with your assessor's acceptance?