Back to Learning Center
Error Fix

SSL Handshake Failed: All Causes and Fixes

9 min read
Updated June 2026By CertNotify Team

"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:

1. Client Hello — browser sends supported TLS versions and cipher suites
2. Server Hello — server picks version and cipher, sends certificate
3. Certificate Verification — client validates certificate chain
4. Key Exchange — both sides derive session keys
5. 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

certificate has expired

Renew the certificate immediately. Check auto-renewal configuration.

hostname/IP does not match

Certificate CN/SAN does not cover this domain. Reissue with correct domains in the SAN.

certificate not trusted

Self-signed or from unknown CA. Install a certificate from a trusted CA, or add CA to client trust store for internal use.

incomplete chain

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.

Test from different networks (mobile hotspot vs corporate WiFi)
Test with and without VPN
Check if antivirus SSL inspection is intercepting connections
Try setting MTU to 1400 bytes for networks with problematic fragmentation

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

Keep your SSL healthy

Most SSL handshake failures stem from expired certificates or configuration drift. CertNotify monitors your certificate health 24/7 and alerts you before problems reach users.