Free tool

Certificate chain checker

See every certificate a server sends, in order, and whether the chain reaches a trusted root. Free, no account.

We read the chain it serves on port 443.

Try example.com, incomplete-chain.badssl.com or untrusted-root.badssl.com.

How a certificate chain works

Your site’s certificate is signed by an intermediate certificate, which is signed by a root certificate. Browsers and operating systems ship with a list of trusted roots. To trust your certificate, a client has to follow the signatures from it, through the intermediates, to one of those roots.

The server’s job is to send its own certificate followed by the intermediates. The root stays on the client. If an intermediate is missing, the client can’t make the link and the connection fails, unless the client fills the gap itself.

How to read the result

  1. Certificate 1 is the site certificate: it should list your domain and be within its dates.
  2. The certificates after it are the intermediates the server sent, each issued by the next one down.
  3. The last one is the root, taken from the trust store when the chain leads to one. If it doesn’t, the result marks the root as untrusted, or shows a torn ticket where the missing intermediate should be.

The chain shown is the one served by the address with the soonest-expiring valid certificate. Under it, Server addresses lists the addresses we checked, up to 4 IPv4 and 4 IPv6: one that sends a broken chain while the others are fine is marked there. A load balancer behind one address answers with one of its servers, so a bad one behind it may not show on a given day.

Common chain errors and how to fix them

Missing intermediate

The server sends only its own certificate. Fix it by serving the full chain file your CA or ACME client provides. With certbot and nginx, that means fullchain.pem, not cert.pem:

nginx
ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

Hosting panels often have a separate “CA bundle” or “chain” field for the intermediates.

Untrusted root or self-signed certificate

The chain ends in a root that isn’t in our checker’s trust store: usually a self-signed certificate, a company’s private CA, or a test setup. For a public site, replace it with a certificate from a public CA. Let’s Encrypt is free.

Expired intermediate

The site certificate is current but an intermediate in the chain has expired. This usually means an old bundle saved on the server. Download the current chain from your CA and serve that.

Hostname mismatch

Not a chain problem, but often reported alongside one: the certificate doesn’t list the domain you visited. Issue one that does, or check that the domain points at the right server.

Check a chain from the command line

This prints every certificate the server sends, with its subject and issuer:

Terminal
openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null

Each certificate appears as a block, starting with “s:” (subject) and “i:” (issuer). The issuer of each should be the subject of the next. More in Fix “unable to get local issuer certificate”.

Questions

Something else? Send us a note, right from the page.

Is the certificate chain checker free?

Yes, with no account. Monitoring with email alerts when a certificate breaks or nears expiry is free for up to 10 domains.

The site works in my browser. Why does the checker say an intermediate is missing?

Browsers cover for it: Chrome downloads the missing intermediate, and Firefox ships a list of known intermediates.

Most other clients don’t: curl, scripts, payment and webhook senders, many apps and monitoring tools. They fail until the server sends the full chain.

Should the server send the root certificate too?

It doesn’t need to. Clients already have the root in their trust store, and sending it only adds bytes to every handshake. The result shows the root from the trust store when the chain leads to one.

Which roots count as trusted?

Those in the copy of Mozilla’s root store bundled with Node.js, which our checker verifies the chain against. Private and company roots show as untrusted.

A chain that checks out here isn’t a browser’s verdict. Browsers apply their own root stores and rules, and this check doesn’t look at revocation or Certificate Transparency.

Can I check a chain on an internal server?

No. The checker connects only to public domain names on port 443, and refuses private, internal and reserved addresses.

Get an email before it expires.

Expiry Watch checks the domain every day and emails you if the certificate’s renewal looks late, or before the certificate or the registration runs out.

Free for up to 10 domains. We confirm your address first, and every email has a one-click unsubscribe.

One quick check

Cloudflare wants to confirm a person is sending this. Nothing is sent until it does.