An incomplete certificate chain means your server sends its own leaf certificate during the TLS handshake but leaves out the intermediate certificate that links it to a trusted root. Desktop Chrome, Firefox, and Edge often paper over this by fetching the missing intermediate automatically, so the site looks fine on your laptop. Mobile browsers, curl, Python, Java, and server to server calls do not, and they reject the connection outright. The result is the classic report: "it works for me but the app and half our users get a certificate error."
This guide explains why the chain matters, how to prove an intermediate is missing, and how to install the full chain so every client trusts your site.
What the chain is and why one link cannot be missing
A public certificate is trusted through a chain. Your leaf certificate (the one issued for your domain) is signed by an intermediate certificate authority, and that intermediate is signed by a root that is already in every device's trust store. Clients trust the root, not your leaf, so they need the intermediate to connect the two.
During the handshake, your server is responsible for presenting the leaf plus every intermediate up to (but not including) the root. If it only presents the leaf, a strict client cannot build a path to a trusted root and treats the certificate as untrusted, even though nothing is wrong with the certificate itself.
Why it works in Chrome but breaks in curl and on phones
The reason for the confusing "works here, fails there" behavior is a feature called AIA fetching (Authority Information Access). Desktop browsers read the AIA extension in your leaf certificate, download the missing intermediate on the fly, and complete the chain silently. That masks the misconfiguration.
Most other clients do not do this. Mobile browsers on fresh installs, curl, wget, Python requests, Node's https module, Java HttpClient, and payment or webhook callers do not fetch or cache intermediates. They see an incomplete chain and fail immediately. So an incomplete chain is not a cosmetic issue; it silently breaks APIs, webhooks, and a large share of real visitors.
How to confirm a missing intermediate
The definitive local test is openssl:
openssl s_client -connect example.com:443 -servername example.com
Look at the verify result. If you see verify error:num=21:unable to verify the first certificate or verify error:num=20:unable to get local issuer certificate, the intermediate is missing from what your server sent. Add -showcerts to print every certificate the server presented, and count them: a leaf with no intermediate is the tell.
You can also confirm it remotely without shell access. Our SSL certificate checker inspects the chain your server actually sends, shows whether the intermediate is present, and flags an incomplete chain along with expiry dates, so you do not have to trust a desktop browser that is quietly fixing the problem for you.
Symptom to cause, at a glance
| What you see | Likely cause | Fix |
|---|---|---|
| Works in Chrome, fails in curl or on Android | Missing intermediate, AIA hides it on desktop | Install leaf plus intermediate (fullchain) |
unable to verify the first certificate in openssl |
Server sent leaf only | Concatenate the intermediate into the chain file |
| Trusted after a full reload, not on first hit | Client cached the intermediate earlier | Serve the intermediate so it never depends on cache |
| Fails only after renewal | New cert installed without its chain file | Point the server at the renewed fullchain |
| Random clients fail intermittently | Wrong or out of order intermediate | Reissue the correct intermediate, leaf first |
How to fix it
The rule to remember is: leaf first, intermediate second, root never. You install the leaf and the intermediate together, in that order, and you never include the root because clients already have it.
- Get the correct intermediate from your certificate authority. Most issuers provide a combined file, often named fullchain.pem or a bundle, that already contains the leaf followed by the intermediate.
- Nginx: point
ssl_certificateat the fullchain file (leaf plus intermediate concatenated), not the leaf-only file, and keepssl_certificate_keyon the private key. Reload nginx. - Apache 2.4.8 and newer: put the leaf and intermediate into the file referenced by
SSLCertificateFile, leaf first. Older Apache usesSSLCertificateChainFilefor the intermediate. Restart Apache. - Load balancers and CDNs: paste the leaf and the intermediate into the certificate body field, in order, when you upload the certificate.
- After reloading, re-run the openssl test and confirm the verify error is gone, then confirm with the SSL certificate checker that the served chain is complete.
Let's Encrypt users usually get this right for free, because certbot writes a fullchain.pem and most guides point the server at it. The classic mistake is pointing the server at cert.pem (leaf only) instead of fullchain.pem after a renewal.
When it is not the chain
A missing intermediate is only one reason for a certificate warning. If the certificate is untrusted right after moving DNS or hosting, the cause is more often that traffic is hitting the wrong server or the certificate was not installed on the new host yet. That is a different fix, covered in SSL certificate shows not secure after a DNS move. If you are standing up a new domain and want to get TLS right alongside SPF, DKIM, DMARC, and DNSSEC from the start, see hardening a new domain. It also helps to confirm your A and AAAA records point where you expect with a quick DNS lookup, since a certificate served from an unexpected IP is a common false alarm.
FAQ
Why does my SSL work in Chrome but not in my mobile app? Desktop Chrome fetches the missing intermediate automatically through AIA fetching, so it hides the problem. Mobile apps and HTTP libraries do not, so they fail on the incomplete chain. Install the intermediate on the server and both will work.
Do I need to include the root certificate? No. Clients already trust the root through their built in trust store. You send the leaf and the intermediate only. Including the root wastes handshake bytes and can occasionally cause its own trust confusion.
How do I know which intermediate to use? Your certificate authority publishes the exact intermediate for the root that signed your certificate, and usually ships it as a bundle or fullchain file. Match the intermediate to your issuer, do not reuse an old one from a previous certificate.
Does an incomplete chain affect email or just the website? It affects anything that terminates TLS, including mail submission and IMAP or SMTP over TLS if those services use the same misconfigured certificate. Mail clients tend to be stricter than desktop browsers, so an incomplete chain often shows up as mail connection errors too.
Why did it break right after certificate renewal? Renewal commonly rewrites the leaf but the server config still points at a leaf-only file, or the automation swapped cert.pem for a new leaf without the chain. Point the server at the renewed fullchain file and reload.
Once the full chain is served, verify it from outside your own desktop browser. A browser that quietly completes the chain for you is exactly the tool that will hide the problem from you.