The usual cause is an incomplete certificate chain: your server sends the leaf certificate but not the intermediate that links it to a trusted root. Some clients can work around that gap and others cannot. The fix is to serve the full chain, for example fullchain.pem from Certbot.
What a chain is
A TLS server proves its identity with a certificate signed by an intermediate certificate authority, which is signed by a root that clients already trust. The client must be able to build the path from your certificate to a root it holds. If the server does not send the intermediate, the client has to find it elsewhere, and not every client will.
TLS 1.3 sets the rules for what the server sends. The end-entity certificate must come first, and each following certificate should certify the one before it. A certificate that is a trust anchor may be left out when peers are known to have it. Intermediates are not in that category for the public web, so send them.
How to spot it
Run a handshake and count what the server sends:
openssl s_client -connect example.com:443 -servername example.com -showcerts
Look at the certificate list. If you see one certificate where you expect two, the intermediate is missing. Also read the verify return code at the end. A message about being unable to get local issuer certificate is the classic sign.
Another check is to compare clients. A desktop browser might succeed while a command line client, a Java service or a mobile library fails. A difference between clients on the same host points to the chain, not the leaf.
Fix it
- Identify the file your server uses for its certificate.
- Replace it with the file that contains the leaf first, followed by the intermediates.
- With Certbot, fullchain.pem holds all certificates, with the server certificate first and intermediates after it. Nginx expects that file for ssl_certificate, and Apache 2.4.8 and later does for SSLCertificateFile. The smaller cert.pem and chain.pem files are separate pieces, for software that wants them split.
- Reload the server and repeat the openssl check.
Other causes to rule out
- Wrong order. Leaf first, then each issuer.
- Extra certificates. Servers sometimes send an old and a new intermediate during a transition. TLS 1.3 tells implementations to tolerate that, but trim it if you can.
- Hostname mismatch, which is a different failure. See hostnames and the SAN field.
- Expired intermediate on your side or a stale trust store on the client.
Do not fix a chain problem by turning verification off. See what to do instead of disabling TLS verification.
Where Safeguard fits
Safeguard scans dependencies and SBOMs for known vulnerabilities, including those in the TLS and crypto libraries your projects pull in, and you can try it with the free scan at gold.safeguard.sh/scan.
Quick check
Do I need to send the root certificate?
Usually not. Clients hold their trust anchors, so send the leaf and the intermediates.
Which Certbot file should my web server use?
fullchain.pem for the certificate and privkey.pem for the key.
Sources
Last reviewed: 19 October 2026.