The TLS handshake failed because the client couldn’t verify the server’s certificate, as the server didn’t provide all the intermediate certificates needed to complete the trust chain back to a root Certificate Authority (CA).
Cause 1: Missing Intermediate Certificates on the Server
Diagnosis: Use openssl s_client -connect your_domain.com:443 -servername your_domain.com and examine the Server certificate section. Look for the Certificate chain output. If it’s short (only the server cert and maybe one other) and doesn’t end with a well-known CA (like Let's Encrypt Authority X3, DigiCert Global Root CA, etc.), you’re missing intermediates.
Fix: Obtain the full certificate chain from your CA provider. This is usually a single .pem file containing your server certificate followed by all necessary intermediate certificates. Configure your web server (e.g., Nginx, Apache) to use this combined file as its certificate.
- Nginx:
ssl_certificate /etc/nginx/ssl/your_domain.com.chained.crt; ssl_certificate_key /etc/nginx/ssl/your_domain.com.key; - Apache:
SSLCertificateFile /etc/ssl/certs/your_domain.com.chained.crt SSLCertificateKeyFile /etc/ssl/private/your_domain.com.key
This works because the client, upon receiving the server’s certificate, expects to also receive any intermediate certificates that link it back to a trusted root. Without these, the client’s trust store, which only contains root CAs, cannot validate the server’s identity.
Cause 2: Incorrect Order of Certificates in the Chain File
Diagnosis: Similar to Cause 1, inspect the output of openssl s_client. Even if all certificates are present, if they are not ordered correctly (server cert first, then intermediate 1, then intermediate 2, etc., up to the root), the client might not be able to build the chain.
Fix: Concatenate your server certificate and intermediate certificates in the correct order: your server certificate should be at the top, followed by intermediate certificates in the order they were issued (closest to the server cert first), ending with the root certificate if your CA provided it.
Example your_domain.com.chained.crt content:
-----BEGIN CERTIFICATE-----
(Your Server Certificate)
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
(Intermediate Certificate 1)
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
(Intermediate Certificate 2)
-----END CERTIFICATE-----
Then update your web server configuration to point to this correctly ordered file. This ensures the client receives the certificates in a sequence it can traverse to establish trust.
Cause 3: Using Only the Server Certificate
Diagnosis: The openssl s_client output shows only your domain’s certificate and no other certificates in the chain.
Fix: Many CAs provide a separate file for intermediate certificates. You need to combine your server certificate with these intermediate certificates into a single file, as described in Cause 1 and 2. Do not configure your server to use only the leaf certificate. The server must present the full path to a trusted root.
Cause 4: Intermediate Certificates Expired or Revoked
Diagnosis: Use openssl s_client as before. If the chain appears complete but the handshake still fails with this error, check the validity dates of the intermediate certificates shown in the chain. Also, check your CA’s portal or use openssl verify -CApath /etc/ssl/certs/ /path/to/your/server.crt to see if intermediates are marked as invalid.
Fix: Request new intermediate certificates from your CA. This is rare unless you’re using a very old or custom-issued certificate. If an intermediate is revoked, you must obtain a new certificate chain from your CA. You would then replace the expired/revoked certificate file on your server with the new one and restart your web server.
Cause 5: Client’s Trust Store Issues (Less Common for Servers)
Diagnosis: This error is almost always a server-side configuration issue. However, if you’re testing from a very old or unusual client, its root CA store might be incomplete or misconfigured, preventing it from trusting the root CA your server’s chain ultimately points to. This is diagnosed by testing from multiple clients and seeing consistent failure.
Fix: Ensure your server’s chain points to a root CA that is widely trusted by modern operating systems and browsers. If you’re using a custom or private CA, clients need to explicitly trust that root CA. For public-facing servers, this is usually not an issue unless you’ve deliberately chained to a less common root.
Cause 6: Load Balancer or CDN Configuration
Diagnosis: If your TLS termination happens at a load balancer (e.g., AWS ELB, Cloudflare) or a CDN, the certificate chain issue might be on that intermediary device, not your origin server. Use openssl s_client pointed at the load balancer’s or CDN’s endpoint.
Fix: Upload the full, correctly ordered certificate chain (server cert + intermediates) to your load balancer or CDN configuration. The specific steps vary by provider, but you’ll typically find a "certificate" or "SSL/TLS" section where you upload your certificate and private key, and often a separate field for "intermediate certificates" or a combined "certificate chain" file.
The next error you’ll likely encounter after fixing the certificate chain is a "Client doesn’t trust your CA" error if your root CA is not in the client’s trust store.