Certificates2026-03-27

What Is an SSL Certificate Chain? (And Why It Matters)

Understand SSL certificate chains — what they are, how root, intermediate, and leaf certificates work together, why chain errors happen, and how to fix them.

sslcertificatetlspkihttpssecurity

What Is an SSL Certificate Chain? (And Why It Matters)

You've deployed your SSL certificate. The certificate itself checks out. But browsers are still throwing NET::ERR_CERT_AUTHORITY_INVALID, or your API clients are failing with UNABLE_TO_GET_ISSUER_CERT. The certificate is valid — so what's wrong?

Almost always, the answer is an incomplete certificate chain. This is one of the most common SSL misconfigurations in production, and it's easy to fix once you understand how certificate chains work.

What Is a Certificate Chain?

An SSL certificate doesn't stand alone — it exists within a hierarchy of trust called a Public Key Infrastructure (PKI). Every certificate is signed by another certificate, forming a chain that leads back to a root certificate authority (CA) that browsers and operating systems inherently trust.

A typical chain has three levels:

Root CA Certificate
    └── Intermediate CA Certificate
            └── Leaf Certificate (your domain)

Each level vouches for the one below it. Your leaf certificate says "I am devdecode.dev, and Let's Encrypt signed me." The intermediate certificate says "I am Let's Encrypt, and the ISRG Root X1 CA signed me." The root certificate says "I am ISRG Root X1, and I am trusted by browsers."

Root Certificates

Root certificates sit at the top of the hierarchy. They are self-signed — the CA signs its own certificate — and they are pre-installed in operating systems and browsers as part of a trusted root store. Mozilla, Microsoft, Apple, and Google each maintain their own root stores.

Root CAs are kept extremely secure. Their private keys are stored offline, in air-gapped hardware security modules (HSMs), in geographically distributed vaults. Compromising a root CA would undermine trust in every certificate it has ever signed.

Intermediate Certificates

Because root keys are so sensitive, CAs don't use them to sign your certificate directly. Instead, the root CA signs one or more intermediate CAs, and the intermediate CA signs your leaf certificate.

This provides a critical security property: if an intermediate CA is compromised, its certificate can be revoked without invalidating the root. The root remains untouched.

You'll typically receive one or two intermediate certificates from your CA alongside your leaf certificate.

Leaf Certificates

The leaf certificate (also called the end-entity certificate or server certificate) is the one issued directly to your domain. It contains your public key, your domain name(s) in the Subject Alternative Names (SANs), and the validity period. This is the certificate you configure in Nginx, Apache, or your load balancer.

Why Chain Validation Matters

When a browser connects to your server, it doesn't just look at your leaf certificate. It walks the entire chain:

  1. It reads your leaf certificate and finds who signed it (the issuer)
  2. It looks for that issuer's certificate — either sent by your server or cached locally
  3. It checks that issuer's signature, then looks for its issuer
  4. It repeats until it reaches a certificate in its trusted root store
  5. If it can build a complete, valid chain to a trusted root, the connection succeeds
  6. If the chain is broken at any point, you get an error

This is what "chain of trust" means in practice — a cryptographically verifiable path from your certificate all the way up to a root that the browser already trusts.

What Happens When the Chain Is Incomplete

If your server only sends the leaf certificate without the intermediates, most browsers will fail to validate it. The behavior varies:

  • Desktop browsers sometimes succeed by fetching missing intermediates using the Authority Information Access (AIA) extension embedded in the certificate — but this is a fallback, not a guarantee, and it adds latency
  • Mobile browsers and API clients (curl, requests, Java's HttpClient) typically fail outright with no fallback
  • Strict TLS clients always fail — this is the correct and expected behavior per the TLS spec

The error messages you'll see depend on the client:

Client Error Message
Chrome NET::ERR_CERT_AUTHORITY_INVALID
Firefox SEC_ERROR_UNKNOWN_ISSUER
curl unable to get local issuer certificate
OpenSSL UNABLE_TO_GET_ISSUER_CERT_LOCALLY
Java sun.security.validator.ValidatorException

Verifying Your Certificate Chain with OpenSSL

OpenSSL is the fastest way to diagnose a chain problem from the command line.

Check what your server is actually sending

openssl s_client -connect devdecode.dev:443 -showcerts

This prints every certificate the server sends during the TLS handshake. Count them — you should see at least two (leaf + intermediate). If you only see one, your chain is incomplete.

Verify the chain against your system's root store

openssl s_client -connect devdecode.dev:443 2>/dev/null | \
  openssl x509 -noout -text | grep -A2 "Issuer\|Subject"

Verify a local certificate file against a CA bundle

openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt your-cert.pem

A successful output looks like:

your-cert.pem: OK

Any other output indicates a chain problem.

Check the chain manually from a PEM file

If you have all your certificates in separate files:

# Verify leaf against intermediate
openssl verify -CAfile intermediate.pem leaf.pem

# Verify intermediate against root
openssl verify -CAfile root.pem intermediate.pem

How to Fix an Incomplete Chain

Your CA should provide all necessary intermediate certificates alongside your leaf. If you're using Let's Encrypt, certbot handles this automatically — the fullchain.pem file it generates already contains your leaf certificate followed by the intermediates.

If you're managing certificates manually, you need to concatenate them in the correct order:

# Order matters: leaf first, then intermediate(s), optionally root last
cat your-domain.crt intermediate.crt > fullchain.pem

# Or with Let's Encrypt files:
cat cert.pem chain.pem > fullchain.pem

Then configure your server to use the full chain file.

Nginx:

ssl_certificate     /etc/ssl/certs/fullchain.pem;
ssl_certificate_key /etc/ssl/private/your-domain.key;

Apache:

SSLCertificateFile    /etc/ssl/certs/your-domain.crt
SSLCertificateChainFile /etc/ssl/certs/intermediate.crt
# Or in Apache 2.4.8+, use a single combined file:
SSLCertificateFile    /etc/ssl/certs/fullchain.pem

After updating your configuration, reload the server and re-run the openssl s_client command to confirm the full chain is being sent.

Inspecting Certificates with DevDecode Tools

You don't always have OpenSSL handy — and even when you do, its output is verbose and hard to read. The SSL Certificate Decoder on DevDecode parses any PEM-encoded certificate and displays the issuer, subject, SANs, validity period, and signature algorithm in a clean, human-readable format. Paste your leaf certificate to immediately confirm who signed it.

The SSL Checker goes further — it connects to your live domain and verifies the entire chain, flagging missing intermediates, expired certificates, and hostname mismatches. Use it after any certificate deployment to confirm everything is configured correctly.

If you're working with PEM files and need to understand what's inside them, the PEM Decoder identifies the block type (certificate, private key, CSR) and decodes the contents. The Certificate Decoder accepts certificates in multiple formats — PEM, DER, or raw base64 — and works out the type automatically.

Summary

  • An SSL certificate chain is a hierarchy: root CA → intermediate CA → leaf certificate
  • Browsers validate the entire chain, walking from your leaf certificate up to a trusted root
  • Intermediate CAs exist to protect root CA keys — a compromised intermediate can be revoked without invalidating the root
  • An incomplete chain (missing intermediates) causes NET::ERR_CERT_AUTHORITY_INVALID and similar errors in strict clients
  • Diagnose chain problems with openssl s_client -connect yourhost:443 -showcerts
  • Fix incomplete chains by concatenating certificates in order — leaf first, then intermediates — into a single fullchain.pem
  • Always verify your deployment with the SSL Checker after any certificate change