SSL/TLS Handshake Failures: ssl_error_handshake_failure and Friends

A handshake failure means client and server never agreed on protocol version, cipher, or certificate. Narrow it down with openssl in one command and fix the mismatch.

What you'll see

Root causes

No shared cipher suite or TLS version

Old clients fail against modern TLS-only servers (TLS 1.0/1.1 disabled), and new clients fail against ancient servers. openssl s_client -connect host:443 -tls1_2 prints the exact failure point.

Missing or mismatched certificate / SNI

A server serving the default (wrong) cert for a name will fail strict clients. openssl s_client -connect host:443 -servername host shows which cert is actually presented.

Wrong port or non-TLS service on a TLS port

Connecting TLS to a plain HTTP port produces immediate handshake garbage. Test: curl -v https://host:8443/ and confirm the service really speaks TLS there.

Fix it

  1. Reproduce the handshake verbosely and read the alert
    openssl s_client -connect example.com:443 -servername example.com </dev/null 2>&1 | head -25
  2. Inspect cert, protocol, and cipher actually negotiated
    openssl s_client -connect example.com:443 -servername example.com </dev/null | openssl x509 -noout -subject -dates
  3. Enable modern but compatible TLS settings (nginx example)
    # ssl_protocols TLSv1.2 TLSv1.3;  ssl_ciphers HIGH:!aNULL:!MD5;  then: sudo nginx -t && sudo systemctl reload nginx
  4. If SNI is the issue, ensure the server returns the right vhost cert
    curl -vI https://example.com 2>&1 | grep -E 'subject|issuer|SSL connection'

Field note

TLS 1.3 changes the handshake design — failures there are almost always cert or middlebox problems, not cipher negotiation. openssl s_client -tls1_2 vs -tls1_3 quickly isolates which protocol path breaks.

Common questions

Why does the handshake fail only from some clients?

Different clients support different TLS versions and cipher lists. Capture the exact negotiation with openssl s_client from a failing client if possible, then widen the server's ssl_protocols/ssl_ciphers to overlap.

Can a firewall cause TLS handshake failures?

Yes — deep-packet-inspection middleboxes that mangle ClientHello can abort handshakes. The tell is openssl succeeding from the server itself but failing across the network path.

Ship it right the first time

Our most-documented failures, packaged as ready-to-ship starter kits: Docker, Kubernetes, and Terraform.

Browse the template store →

One-time. Yours to modify. Instant download from the NinjaOps template store.