What a TLS Certificate Chain Is
A TLS certificate chain (also called a certificate path or chain of trust) is the ordered sequence of certificates that links your server's certificate to a Certificate Authority root that browsers and operating systems inherently trust. No certificate is trusted in isolation — every certificate's trustworthiness derives from the signature of the certificate above it in the chain, all the way back to a root CA whose public key is embedded in the browser or OS trust store.
A correctly configured chain for a typical HTTPS connection looks like this:
CERTIFICATE CHAIN — correctly ordered:
[1] Root CA Certificate
"DigiCert Global Root CA"
Self-signed, trusted by browser trust store
↓ signs
[2] Intermediate CA Certificate
"DigiCert TLS RSA SHA256 2020 CA1"
Issued by Root CA
↓ signs
[3] Leaf Certificate (your server's certificate)
"example.com"
Issued by Intermediate CA
← This is what your server presents to clients
The browser starts at the leaf certificate, verifies that it was signed by the intermediate, verifies that the intermediate was signed by the root, and confirms the root is in its trust store. If any link in this verification path is missing, unverifiable, or out of order, the chain validation fails and the browser presents a certificate error to the user.
The Three Certificate Roles: Root, Intermediate, and Leaf
Understanding the role and properties of each certificate type is essential for diagnosing chain errors.
Root CA certificates
Root certificates are self-signed — they are signed by their own private key. Their trustworthiness does not come from another certificate; it comes from being included in browser and OS trust stores. Browser vendors (Google, Mozilla, Apple, Microsoft) and operating system vendors maintain lists of trusted root CAs that go through rigorous auditing processes, governed by the CA/Browser Forum, before inclusion.
Root CA private keys are kept offline in air-gapped, physically secured facilities. They are never used directly to sign server certificates — that's the intermediate CA's job. If a root CA private key were compromised, every certificate it signed would immediately become untrustworthy and the root would be removed from all trust stores.
Intermediate CA certificates
Intermediate certificates are signed by a root CA (or by another intermediate CA in a multi-level hierarchy). They are the operational layer of the PKI — they sign end-entity certificates on behalf of the root without exposing the root private key.
This is the certificate type most likely to be missing from your server configuration. Your CA provides you with one or more intermediate certificates when they issue your certificate. These must be included in your server's TLS configuration alongside your leaf certificate. Forgetting to install them, or installing only the leaf certificate, is the most common chain error.
Leaf certificates (end-entity certificates)
The leaf certificate is the one your server presents to clients. It contains your domain name (and any SANs), your public key, validity dates, and the signature of the issuing intermediate CA. Leaf certificates cannot sign other certificates — the CA constraint in their extensions prevents it.
How Chain Validation Works
When a TLS handshake begins, the server sends its certificate (and ideally the full chain) to the client. The client then builds and validates the certificate path:
- Start at the leaf certificate. Extract the issuer field — this identifies the certificate that should have signed this one.
- Find the issuing certificate. Check whether the client already has it cached, or whether the server sent it as part of the chain. If neither, check whether it can be downloaded via the Authority Information Access (AIA) extension in the certificate.
- Verify the signature. Use the issuing certificate's public key to verify the cryptographic signature on the leaf certificate. If the signature is valid, the leaf certificate was genuinely issued by that CA.
- Repeat up the chain. Take the issuing certificate, find its issuer, verify its signature — until reaching a self-signed root certificate.
- Check the root against the trust store. Verify that the root certificate is in the client's trusted root store. If it is, the entire chain is trusted.
If any step fails — a missing intermediate, an invalid signature, a root not in the trust store, an expired intermediate, a revoked certificate — the validation fails and the connection is refused or warned.
ℹ️ Note: Some clients (notably Chrome on desktop) can attempt to download missing intermediate certificates via the AIA extension URL embedded in the leaf certificate. This is called AIA fetching. This behaviour masks incomplete chain configurations from some users while still breaking others — particularly mobile clients, API clients, and older browsers that don't implement AIA fetching. Never rely on AIA fetching as a substitute for correctly configuring the chain on your server.
Why Servers Must Send the Full Chain
Root certificates are pre-installed in trust stores. Clients don't need to receive them — they already have them. But intermediate certificates are not pre-installed in most client trust stores.
This means: your server must send all intermediate certificates between your leaf certificate and the root. A one-level hierarchy (root → leaf, no intermediate) is rare in practice — almost all commercially issued and Let's Encrypt certificates have at least one intermediate. Modern multi-level PKI hierarchies sometimes have two intermediates between the root and the leaf.
The server's TLS configuration is where the intermediate certificate(s) are specified. The exact method varies by web server:
- Nginx: The
ssl_certificatedirective should point to a file containing the leaf certificate followed by all intermediate certificates, in order from leaf to root. - Apache: Use
SSLCertificateFilefor the leaf certificate andSSLCertificateChainFilefor the intermediate(s), or combine them into a single file referenced bySSLCertificateFile. - Let's Encrypt / Certbot: The
fullchain.pemfile contains both the leaf certificate and all required intermediates concatenated — always usefullchain.pemas your certificate file, nevercert.pemalone.
⚠️ Warning: Using
cert.peminstead offullchain.pemin Let's Encrypt configurations is one of the most common chain errors.cert.pemcontains only the leaf certificate.fullchain.pemcontains the leaf plus the intermediates. Always usefullchain.pemfor yourssl_certificate(Nginx) orSSLCertificateFile(Apache) directive.
Common Certificate Chain Errors
Incomplete chain (missing intermediate)
Symptom: Browser shows "certificate not trusted" or "SEC_ERROR_UNKNOWN_ISSUER." API clients return SSL verification errors. Mobile clients almost always fail — they typically don't perform AIA fetching.
Cause: The server is sending only the leaf certificate without the intermediate CA certificate(s). The client cannot build the chain to a trusted root.
Fix: Add the intermediate certificate(s) to your server configuration. See the fix section below.
Misordered chain
Symptom: Some clients accept the connection, others fail. The chain appears complete when inspected with some tools but fails with others.
Cause: The certificates in the chain file are in the wrong order. The required order is leaf first, then intermediate(s) from the one closest to the leaf up toward the root. Sending root → intermediate → leaf instead of leaf → intermediate → root confuses some TLS implementations.
Correct order:
-----BEGIN CERTIFICATE-----
[Leaf certificate — your domain]
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
[Intermediate CA certificate]
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
[Root CA certificate — optional, often omitted]
-----END CERTIFICATE-----
Self-signed certificate served to public clients
Symptom: All browsers and most clients show a certificate error. The error message explicitly says "self-signed" or "not trusted."
Cause: The certificate was signed by a private key you control, not by a publicly trusted CA. Self-signed certificates are fine for internal systems, development environments, and testing — but they will never be trusted by public browser trust stores without manual exception.
Fix: Replace the self-signed certificate with one issued by a publicly trusted CA. Let's Encrypt issues free DV certificates valid for 90 days with automated renewal.
Expired intermediate certificate
Symptom: The leaf certificate appears valid and unexpired, but chain validation fails. The error may reference a specific intermediate certificate's expiry.
Cause: An intermediate CA certificate in the chain has expired. This is uncommon but has caused high-profile outages — notably when Let's Encrypt's DST Root CA X3 cross-signed certificate expired in September 2021, breaking connections for clients that hadn't updated their trust stores.
Fix: Obtain the updated intermediate certificate from your CA and replace the expired one in your server configuration. Most CAs publish current intermediate certificates on their website.
Wrong intermediate for the issuing CA
Symptom: Chain validation fails. OpenSSL reports "unable to get local issuer certificate" or similar.
Cause: The intermediate certificate in the server configuration doesn't match the CA that actually issued the leaf certificate. This can happen when a certificate is reissued by a different CA or intermediate without updating the chain file.
Fix: Download the correct intermediate certificate from the CA that issued your specific leaf certificate. The AIA extension in your leaf certificate contains a URL to the issuing CA's certificate — use this to identify and fetch the correct intermediate.
How to Check Your Certificate Chain
Via openssl
# Check the full chain presented by a server
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null
# Show each certificate in the chain with subject and issuer
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -text | grep -E "Subject:|Issuer:"
# Verify the chain is complete and trusted
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| grep -E "Verify return code|Certificate chain"
# Check a specific certificate file's issuer and subject
openssl x509 -in certificate.crt -noout -subject -issuer
# Verify a certificate file against a CA bundle
openssl verify -CAfile /path/to/ca-bundle.crt certificate.crt
The Verify return code line in the openssl s_client output is the key diagnostic:
Verify return code: 0 (ok)— chain is complete and trustedVerify return code: 2 (unable to get issuer certificate)— intermediate is missingVerify return code: 20 (unable to get local issuer certificate)— wrong intermediateVerify return code: 21 (unable to verify the first certificate)— leaf certificate issue
Via the SSL Certificate Checker
Use our SSL Certificate Checker to inspect any domain's full certificate chain without command-line access. It shows each certificate in the chain, the subject and issuer of each, expiry dates, and whether the chain validates correctly against public trust stores.
Checking the chain order in a PEM file
# List all certificates in a PEM bundle file and their subjects
openssl crl2pkcs7 -nocrl -certfile fullchain.pem \
| openssl pkcs7 -print_certs -noout \
| grep "subject="
# Expected output order:
# subject=CN = example.com ← leaf (first)
# subject=CN = R3, O = Let's Encrypt, C = US ← intermediate (second)
How to Fix Chain Configuration Errors
Step 1: Identify the correct intermediate(s)
Find the issuer of your leaf certificate:
openssl x509 -in your-certificate.crt -noout -issuer
# issuer=CN = R3, O = Let's Encrypt, C = US
Then locate and download the current intermediate certificate from your CA. For Let's Encrypt, the current intermediate certificates are published at letsencrypt.org/certificates. For commercial CAs, check their website or the AIA URL in your certificate:
openssl x509 -in your-certificate.crt -noout -text \
| grep -A2 "Authority Information Access"
# CA Issuers - URI:http://r3.i.lencr.org/
Fetch the intermediate from the AIA URL:
curl -s http://r3.i.lencr.org/ | openssl x509 -inform DER -out intermediate.crt
Step 2: Build the correct chain file
Concatenate the certificates in the correct order — leaf first, then intermediate(s):
cat your-certificate.crt intermediate.crt > fullchain.crt
# Verify the concatenated file contains the correct certs in the right order
openssl crl2pkcs7 -nocrl -certfile fullchain.crt \
| openssl pkcs7 -print_certs -noout | grep "subject="
Step 3: Update your web server configuration
Nginx:
server {
listen 443 ssl;
ssl_certificate /etc/ssl/certs/fullchain.crt; # leaf + intermediates
ssl_certificate_key /etc/ssl/private/your-key.key;
}
Apache:
SSLEngine on
SSLCertificateFile /etc/ssl/certs/your-certificate.crt
SSLCertificateChainFile /etc/ssl/certs/intermediate.crt
# Or in Apache 2.4.8+, combine into SSLCertificateFile:
# SSLCertificateFile /etc/ssl/certs/fullchain.crt
Let's Encrypt / Certbot (Nginx):
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # correct
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# Never use cert.pem — that's leaf only, no intermediates
Step 4: Reload the web server and verify
# Test Nginx config before reloading
nginx -t
# Reload Nginx
systemctl reload nginx
# Test Apache config before reloading
apachectl configtest
# Reload Apache
systemctl reload apache2
# Verify the chain is now complete
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| grep "Verify return code"
# Expected: Verify return code: 0 (ok)
After confirming the fix with openssl, run the SSL Certificate Checker to verify the full chain as seen from an external vantage point — this confirms the fix is visible to clients, not just locally.
For ongoing certificate health — including expiry monitoring for both the leaf certificate and the intermediate certificates in your chain — see our SSL Certificate Expiry Monitoring guide.
Chain Validation in Non-Browser Clients
Browser trust stores and non-browser TLS clients can behave differently during chain validation, and this creates situations where a chain error affects some clients but not others.
cURL: By default, cURL uses the system CA bundle and validates the full chain. A missing intermediate will produce SSL certificate problem: unable to get local issuer certificate. Use curl -v to see detailed TLS handshake information.
Python requests / urllib3: These libraries use the system CA bundle (via certifi on most installations). Chain errors produce ssl.SSLCertVerificationError.
Java: Java maintains its own trust store (the JDK cacerts file) separate from the OS trust store. A certificate trusted by browsers may not be trusted by Java applications if the intermediate isn't in the Java trust store or the chain isn't sent correctly.
Mobile apps (iOS/Android): Mobile clients typically do not perform AIA fetching and are strict about receiving the complete chain. An incomplete chain that Chrome on desktop silently fixes via AIA will fail hard on iOS and Android API clients.
Monitoring tools: Most uptime monitors and synthetic monitoring tools do validate certificate chains. An incomplete chain may cause monitoring alerts even if browsers appear unaffected due to AIA fetching.
💡 Tip: Always test your certificate chain with both
openssl s_client(which simulates a strict client without AIA fetching) and a browser (which may mask problems via AIA fetching). Ifopensslreports a chain error but browsers appear fine, you have an incomplete chain that is silently compensated for by some clients — fix it before a strict client (mobile app, API client, monitoring tool) encounters it in production.
Frequently Asked Questions
Q: My site works fine in Chrome but fails in our mobile app — could it be the certificate chain?
Almost certainly yes. Chrome on desktop implements AIA fetching, which automatically downloads missing intermediate certificates. Mobile HTTP clients typically don't do this. If Chrome succeeds but your mobile app (or curl, or Python requests) fails with an SSL error, run openssl s_client to check your chain — the result will tell you whether intermediates are missing without AIA assistance.
Q: Do I need to include the root certificate in my chain file?
No, and it's slightly better not to. Root certificates are already in client trust stores — sending them in the chain is redundant and adds a small amount of unnecessary data to each TLS handshake. Your chain file should contain the leaf certificate followed by any intermediate certificates, stopping before the root. Some configurations include the root harmlessly; others may produce warnings. Omitting it is the standard practice.
Q: Let's Encrypt certificates used to work but now clients are failing — what changed?
This is likely the intermediate certificate rotation. Let's Encrypt periodically rotates its intermediate CAs (R3, E1, etc.) and their cross-signatures. If your server is serving an outdated intermediate certificate from a previous issuance, it may have expired or been superseded. Run certbot renew --force-renewal to fetch a fresh certificate with the current intermediate, then verify the chain with openssl s_client.
Q: How do I fix a chain error on a CDN like Cloudflare or Fastly?
CDN-terminated TLS is configured in the CDN's certificate management interface, not on your origin server. Log in to the CDN's dashboard, navigate to the SSL/TLS or certificate settings, and upload the full certificate chain (leaf + intermediates) in the correct order. Cloudflare's managed certificates are handled entirely by Cloudflare and don't require manual chain management — chain errors on Cloudflare-managed certificates should be reported to Cloudflare support.
Q: Can an intermediate certificate itself expire and cause chain failures?
Yes. Intermediate certificate expiry is less common than leaf certificate expiry but does happen — and when it does, it can affect thousands of sites simultaneously if they all depend on the same intermediate CA. When an intermediate expires, obtain the updated intermediate from your CA and update your server configuration. The September 2021 Let's Encrypt DST Root CA X3 expiry was a prominent example of this class of problem affecting older Android devices.
Q: What does "certificate chain contains anchor" mean in some tools?
This warning appears when you've included the root (anchor) certificate in your chain file. The root is self-signed and already in the trust store — it doesn't need to be in the chain. It's not a breaking error, just unnecessary. Remove the root certificate from your chain file to eliminate the warning and slightly reduce handshake size.
Next Steps
After fixing chain errors, verify the full certificate health with our SSL Certificate Checker — it checks the chain, expiry, SANs, and trust store validation in a single scan.
For the broader TLS health picture beyond the chain — including expiry monitoring, auto-renewal failures, and wildcard certificate management — see our SSL Certificate Expiry Monitoring guide.
To complete your HTTPS security posture after resolving certificate issues, read our HTTP Security Headers guide, which covers HSTS, CSP, and the response headers that protect users once the TLS connection is established.
Browse all security guides on DNSnexus for related topics.