The TLS handshake is failing because the client doesn’t trust the server’s certificate.
Common Causes and Fixes
1. Expired Certificate
- Diagnosis: Check the certificate’s expiration date on the server.
openssl x509 -in /etc/ssl/certs/your_domain.crt -noout -dates - Fix: Renew the certificate with your Certificate Authority (CA). For example, if using Let’s Encrypt, run:
sudo certbot renew sudo systemctl reload nginx # or apache2ctl graceful - Why it works: A certificate is only valid for a specific period. Once expired, it’s no longer trusted by clients. Renewing it issues a new, valid certificate.
2. Incorrect Certificate Chain (Missing Intermediate Certificates)
- Diagnosis: Use
openssl s_clientto inspect the certificate chain presented by the server.
Compare the issuer with the CA’s intermediate certificate bundle.openssl s_client -connect your_domain.com:443 -servername your_domain.com </dev/null | openssl x509 -noout -text | grep "Issuer:" - Fix: Concatenate the server certificate, any necessary intermediate certificates, and the root CA certificate into a single file (often named
fullchain.pemor similar) and configure your web server to use this file. For Nginx:
For Apache:ssl_certificate /etc/letsencrypt/live/your_domain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/your_domain.com/privkey.pem;SSLCertificateFile /etc/letsencrypt/live/your_domain.com/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/your_domain.com/privkey.pem - Why it works: Browsers and clients need to trace the certificate’s authenticity back to a trusted root CA. If intermediate certificates are missing, the client can’t complete this chain of trust.
3. Certificate Issued to the Wrong Domain Name (Hostname Mismatch)
- Diagnosis: Check the "Subject Alternative Name" (SAN) or "Common Name" (CN) field of the certificate.
Ensure the domain you’re accessing (openssl x509 -in /etc/ssl/certs/your_domain.crt -noout -text | grep -A 1 'Subject Alternative Name'your_domain.com) is listed. - Fix: Reissue the certificate from your CA, ensuring all required domain names (including
www.your_domain.comif applicable) are included in the request. Then, update your web server configuration to point to the new certificate and key files. - Why it works: TLS relies on verifying that the certificate presented matches the hostname the client is trying to connect to. If they don’t match, the connection is considered insecure.
4. Server Not Presenting the Correct Certificate File
- Diagnosis: Use
openssl s_clientto see which certificate the server is actually serving.
Compare the output subject with the expected certificate.openssl s_client -connect your_domain.com:443 -servername your_domain.com </dev/null | openssl x509 -noout -subject - Fix: Verify your web server’s SSL configuration points to the correct certificate and private key files. For example, in Nginx:
Reload your web server after changes:ssl_certificate /etc/letsencrypt/live/your_domain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/your_domain.com/privkey.pem;sudo systemctl reload nginx. - Why it works: The web server might be configured to use an old, expired, or incorrect certificate file, even if a valid one exists on the system.
5. Client-Side Trust Issues (Less Common for Browsers, More for Services)
- Diagnosis: If a specific client service is failing, check its trust store. For example, on a Linux client:
Verify the issuer is in the client’s trusted CA bundle (e.g.,openssl s_client -connect your_domain.com:443 -servername your_domain.com </dev/null | openssl x509 -noout -issuer/etc/ssl/certs/ca-certificates.crt). - Fix: If the issuing CA is not trusted by the client, you may need to manually add the CA’s root certificate to the client’s trust store. For Debian/Ubuntu:
sudo cp your_ca_root.crt /usr/local/share/ca-certificates/ sudo update-ca-certificates - Why it works: The client needs to trust the Certificate Authority that signed the server’s certificate. If the root CA is missing from the client’s local trust store, it cannot validate the certificate.
6. Certificate Revocation Issues (CRL/OCSP)
- Diagnosis: Some clients may check Certificate Revocation Lists (CRLs) or Online Certificate Status Protocol (OCSP) responses. If the CA’s revocation servers are unreachable or the certificate is listed as revoked, this error can occur. This is harder to diagnose directly without client logs.
- Fix: This is usually a problem with the CA or the network path to the CA’s revocation servers. Ensure your server is configured to provide OCSP stapling if possible, which can improve performance and reliability.
For Nginx:
ssl_stapling on; ssl_stapling_verify on; ssl_trusted_certificate /etc/letsencrypt/live/your_domain.com/chain.pem; # Often chain.pem or fullchain.pem resolver 8.8.8.8 8.8.4.4 valid=300s; # Use your preferred DNS resolvers resolver_timeout 10s; - Why it works: OCSP stapling allows the server to proactively fetch and present the revocation status of its own certificate to clients during the handshake, reducing reliance on the client reaching the CA’s revocation servers directly.
The next error you might encounter is an "SSL_ERROR_RX_RECORD_TOO_LONG" if the TLS configuration is fundamentally broken or if there’s a proxy interfering with the handshake.