Skip to content
Cloudzyro
Troubleshooting

SSL handshake failed: what it means and how to fix it

Kofi Agyem

, Founder and CEO, CloudzyroPublished · 5 min read

On this page
  1. 1. The short answer
  2. 2. What happens in a TLS handshake
  3. 3. Where you'll see it
  4. 4. What causes it
  5. 5. Fixes for visitors, quickest first
  6. 6. Fixes for site owners
  7. 7. How to check
  8. 8. Sources

An SSL handshake failure means client and server couldn't agree how to secure the connection. Causes, Cloudflare error 525, and how to test with openssl.

1. The short answer

An SSL handshake failure means the client and the server couldn't agree on how to secure the connection, so it was closed before any page was sent. The handshake is where they pick a TLS version and cipher, and where the server proves who it is with its certificate. If they share no version or cipher, the certificate can't be used, or something interferes, the handshake fails.

You'll meet it as Cloudflare's Error 525: SSL handshake failed, as browser errors like ERR_SSL_VERSION_OR_CIPHER_MISMATCH, or in tools and code as handshake failure. In nearly every case the fix is on the server: modern TLS versions, a valid certificate for the name, and support for SNI.

2. What happens in a TLS handshake

  1. Client hello. The client says which TLS versions and ciphers it supports, which site it wants (SNI, the server name indication), and sends key material.
  2. Server hello. The server picks a version and cipher both support, and sends its own key material.
  3. Certificate. The server sends its certificate chain and proves it holds the private key.
  4. Finished. Both sides confirm. With TLS 1.3 this all takes one round trip; then encrypted HTTP begins.

A failure at any step aborts the connection. The side that gives up usually sends an alert, such as handshake_failure (no shared settings) or protocol_version (no shared version), which is the text you see in logs.

3. Where you'll see it

  • Cloudflare: Error 525, SSL handshake failed, between Cloudflare and the site's server. Its cousin, Error 526, means the origin's certificate is invalid under Full (strict).
  • Chrome and Edge: This site can't provide a secure connection, with ERR_SSL_VERSION_OR_CIPHER_MISMATCH or ERR_SSL_PROTOCOL_ERROR.
  • Firefox: Secure Connection Failed, with codes like SSL_ERROR_NO_CYPHER_OVERLAP or SSL_ERROR_UNSUPPORTED_VERSION.
  • curl: (35) ... sslv3 alert handshake failure or tlsv1 alert protocol version.
  • Code: Java's SSLHandshakeException, Python's SSLError with HANDSHAKE_FAILURE, Node's EPROTO.

4. What causes it

  • No shared TLS version. The server offers only TLS 1.0 or 1.1, which current clients refuse, or only TLS 1.3 for a client that's too old for it.
  • No shared cipher. The server allows only ciphers the client doesn't have, often after over-zealous hardening.
  • SNI problems. The client doesn't send the site's name, or the server has no certificate for it, and aborts.
  • No certificate configured on the HTTPS port, or a certificate whose key doesn't match.
  • A client certificate is required (mutual TLS) and the client didn't send one.
  • Something in the middle: antivirus, a company proxy, a captive portal or a firewall that inspects TLS.
  • On Cloudflare (525): the origin isn't listening on 443, has no certificate, doesn't support SNI or shares no cipher with Cloudflare, while the zone's SSL mode is Full or Full (strict).
  • Wrong clock on either side, which breaks certificate validation.

5. Fixes for visitors, quickest first

  1. Check your date and time are set automatically.
  2. Update your browser and operating system. Very old systems may not support TLS 1.2 or trust today's root certificates.
  3. Try another network. On public Wi-Fi, sign in through its page first.
  4. Pause antivirus HTTPS scanning or your VPN briefly to test.
  5. If it fails everywhere, it's the site. Let the owner know.

6. Fixes for site owners

  1. Test the handshake with openssl s_client, forcing each version (below).
  2. Enable TLS 1.2 and 1.3, and disable SSL 3.0, TLS 1.0 and 1.1. Use a current recommended cipher list rather than a hand-trimmed one.
  3. Serve a valid certificate for every name, with its full chain and the matching private key.
  4. For mutual TLS, make sure clients that should connect have a certificate, and that public pages don't require one.
  5. For Cloudflare 525: make sure the origin listens on 443 with a certificate and supports SNI. Then use Full (strict) with a valid origin certificate. Don't switch to Flexible to hide it: that sends traffic to your server unencrypted and often causes redirect loops.
  6. For API clients, update the runtime (Java, Python, OpenSSL) so it supports TLS 1.2 or later and current root certificates.

On Cloudzyro Sites & Apps, TLS versions, ciphers and certificates are managed for you, and every site sits behind Cloudflare. If your DNS is also at Cloudflare, set your domain's records to DNS only (gray cloud), not Proxied. CAA records, if any, must allow letsencrypt.org, pki.goog and ssl.com. The site's Domains tab and the domain troubleshooting guide say what's needed.

7. How to check

# Try a normal handshake, sending SNI like a browser does
openssl s_client -connect www.example.com:443 -servername www.example.com

# Force one version at a time
openssl s_client -connect www.example.com:443 -servername www.example.com -tls1_3
openssl s_client -connect www.example.com:443 -servername www.example.com -tls1_2

# Test an origin behind Cloudflare directly (use the origin's IP)
curl -v --resolve www.example.com:443:203.0.113.10 https://www.example.com/

# List the versions and ciphers a server accepts (needs nmap)
nmap --script ssl-enum-ciphers -p 443 www.example.com

If -tls1_2 and -tls1_3 both fail with handshake failure or protocol version, the server's TLS settings are wrong. If both fail only when -servername is missing, the server depends on SNI, which is normal for modern clients. The --resolve test bypasses Cloudflare, so it shows whether the origin can complete a handshake on its own, which is exactly what error 525 is about.

8. Sources

Questions

What does SSL handshake failed mean?
Before any page is sent over HTTPS, the browser and server agree on a TLS version, encryption and certificate. A handshake failure means that agreement couldn't be reached, so the connection was closed.
What is Cloudflare error 525?
Error 525, SSL handshake failed, means Cloudflare couldn't complete a TLS handshake with the site's own server, the origin. It happens with Cloudflare's Full and Full (strict) modes when the origin has no working HTTPS.
Is an SSL handshake failure my fault?
Sometimes. A wrong clock, an outdated browser or operating system, antivirus HTTPS scanning or a network that intercepts traffic can cause it. If it fails on every device, the server's TLS settings are the problem.
Is SSL the same as TLS?
TLS replaced SSL years ago, and every SSL version is now insecure and disabled. People still say SSL out of habit. Today's connections use TLS 1.2 or TLS 1.3.
Which TLS versions should my server support?
TLS 1.2 and TLS 1.3. TLS 1.0 and 1.1 are deprecated by RFC 8996 and refused by current browsers.
Why does my API client fail when the browser works?
Browsers are forgiving in places where libraries aren't. A server missing an intermediate certificate, requiring SNI or offering only newer ciphers can work in Chrome and fail in an older Java, Python or OpenSSL client. Test with openssl s_client and fix the server's chain and settings.

Put your site online free

From your AI tool, Git or a zip, with every version kept.