SSL Handshake Failed: All Causes and Fixes
"SSL handshake failed" is one of the most frustrating errors because it can stem from a dozen different causes. This guide covers every common scenario with specific diagnostics and fixes for each.
What Happens During a TLS Handshake
The handshake is a multi-step negotiation that must succeed before any data is exchanged. If any step fails, the connection is terminated with a handshake failure:
- Client Hello: browser sends supported TLS versions and cipher suites.
- Server Hello: server picks version and cipher, sends certificate.
- Certificate Verification: client validates certificate chain.
- Key Exchange: both sides derive session keys.
- Finished: encrypted connection established.
Cause 1: Cipher Suite Mismatch
Client and server share no common cipher suites. You will see: handshake_failure (40) or no ciphers available.
# Check server cipher suites nmap --script ssl-enum-ciphers -p 443 yourdomain.com # Or with OpenSSL openssl s_client -connect yourdomain.com:443 -cipher "ECDHE-RSA-AES256-GCM-SHA384"
# Nginx fix — modern cipher configuration ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305; ssl_prefer_server_ciphers off;
Cause 2: TLS Protocol Version Mismatch
Client requires TLS 1.2+ but server only offers TLS 1.0/1.1 (or vice versa if client is old).
# Test each version openssl s_client -connect yourdomain.com:443 -tls1_2 2>&1 | grep "Cipher is" openssl s_client -connect yourdomain.com:443 -tls1_3 2>&1 | grep "Cipher is"
Ensure server supports TLSv1.2 TLSv1.3 minimum. For Nginx: ssl_protocols TLSv1.2 TLSv1.3;
Cause 3: Certificate Validation Failure
Renew the certificate immediately. Check auto-renewal configuration.
Certificate CN/SAN does not cover this domain. Reissue with correct domains in the SAN.
Self-signed or from unknown CA. Install a certificate from a trusted CA, or add CA to client trust store for internal use.
Add intermediate certificates to the ssl_certificate file (fullchain.pem).
Cause 4: SNI (Server Name Indication) Issues
SNI allows multiple certificates on one IP. If the client does not send SNI, the server may present the wrong certificate.
# With SNI (correct) openssl s_client -connect yourdomain.com:443 -servername yourdomain.com # Without SNI (may get wrong cert) openssl s_client -connect 203.0.113.1:443 -noservername
Old clients (Java 6, Android 2.x, IE 6 on XP) do not support SNI. If you must support them, use a dedicated IP per certificate or a unified certificate (multi-domain).
Cause 5: Firewall or Middlebox Interference
DPI (Deep Packet Inspection) firewalls, IDS/IPS, and enterprise proxies can corrupt or terminate TLS handshakes. Symptoms: works on some networks, fails on others; works without VPN, fails with VPN.
Cause 6: Client Certificate (mTLS) Issues
For mutual TLS (mTLS) setups, the server requires a client certificate. Error: certificate required. Ensure your API client is configured with the correct client certificate and private key. Check that the client cert was signed by the CA your server trusts for client auth.
# Enable verbose TLS logging for debugging SSLKEYLOGFILE=/tmp/ssl.log curl -v https://yourdomain.com # Java: add system property -Djavax.net.debug=ssl:handshake:verbose
Use our free SSL Certificate Checker and TLS Checker to diagnose certificate and protocol issues on any domain without installing any tools.