Aller au contenu principal

Guides / Corriger : guides pour les erreurs que l'on rencontre vraiment

SSL handshake failed: causes and how to diagnose it

An SSL (TLS) handshake fails when the client and server cannot agree on a protocol version or cipher suite, when the certificate the server presents is expired, wrong for the hostname or missing a required intermediate, or when something between the two, a proxy, antivirus software or a firewall, interferes with the exchange before it completes. The fix depends on which of those it is, and the handshake itself, run manually with a command-line tool, tells you which one.

What actually breaks a handshake?

  • Protocol version mismatch. A client offering only TLS 1.0 or 1.1 against a server that now requires 1.2 or 1.3, or the rarer reverse where an old embedded client or a legacy payment terminal cannot speak the newer version a server has moved to, ends the negotiation before either side even reaches a certificate.
  • No shared cipher suite. Even with a matching version, the client and server each offer a list of cipher suites, and if the intersection of the two lists is empty, the handshake cannot continue. This shows up after a server hardens its configuration and drops older ciphers that some clients still depend on.
  • Expired or not-yet-valid certificate. Every certificate carries a validity window, and a client checks the current date against it as part of validating the chain. An expired certificate, or a clock on either the server or the client that has drifted far enough, fails the handshake the same way.
  • Wrong hostname. The certificate's Subject Alternative Name list has to include the exact hostname the client is connecting to. A certificate issued for www.example.com does not automatically cover example.com or api.example.com, and a mismatch here is a validation failure, not a version or cipher problem.
  • Missing intermediate certificate. A server certificate chains up to a root through one or more intermediate certificates, and it is the server's job to send that whole chain, not just its own leaf certificate. When a server sends only the leaf, a browser that already has the intermediate cached, because it visited another site using the same issuer, connects fine, while a client with an empty cache, or a command-line tool that does not opportunistically fetch missing intermediates, fails. This is the classic "works in one browser, fails in another" report.
  • SNI missing or ignored on shared hosting. A server fronting multiple certificates on one IP address needs the hostname from the ClientHello's SNI extension to pick the right one. An old client that never sends SNI, or a server that ignores it and always serves a default certificate, ends up presenting the wrong certificate for the hostname requested, which then fails hostname validation.
  • Clock skew on the client. Even a correctly issued, currently valid certificate looks expired, or not yet valid, to a client whose own clock is wrong. This is common on devices that have been powered off for a long time or that lost their time sync.
  • An interception proxy or antivirus. Corporate TLS-inspection proxies and some antivirus suites intercept outbound connections and re-sign them with their own certificate. If that certificate is not trusted by the client, or the interception tool cannot keep up with a newer TLS version or cipher, the handshake fails in a way that looks identical to a real server misconfiguration from the outside.

How do you tell these apart from the command line?

Two commands cover almost every case, run directly against the host rather than through a browser, which hides most of the detail behind a generic error page.

openssl s_client -connect host-tracker.com:443 -servername host-tracker.com

This opens a real TLS connection and prints the entire certificate chain the server sent, the negotiated protocol version and cipher suite, and the verification result. The -servername flag is what sends SNI; leaving it off is the single most common mistake when testing a shared-hosting or CDN-fronted domain, since without it the server has no hostname to pick a certificate by and may return its default one instead of the one you meant to check. Look for three things in the output: a Verify return code: 0 (ok) line at the end (anything else names the specific validation failure), the certificate chain under "Certificate chain" (a chain with only one entry, index 0, means the intermediate is missing), and the Protocol and Cipher lines to confirm what was negotiated.

curl -Iv https://host-tracker.com

The -v flag prints the TLS negotiation as it happens, prefixed with *, ahead of the HTTP response headers curl's -I normally shows. A failure here reads as an explicit error line rather than a hang: SSL certificate problem: certificate has expired, unable to get local issuer certificate (a missing intermediate), or SSL_ERROR_SYSCALL style connection resets that point at something interfering with the connection rather than the certificate itself. Because curl uses your system's trust store by default, a result that differs from a browser's is often the clock-skew or interception-proxy case rather than a genuine server problem.

Which cause matches which symptom?

SymptomLikely cause
Fails on old devices only, works on current browsersProtocol version or cipher suite the old client cannot speak
Works in Chrome, fails in curl or an older browserMissing intermediate certificate, masked by the working browser's cached copy
Fails for one hostname, works for a sibling on the same serverWrong hostname on the certificate, or SNI not being sent or honored
Fails everywhere, `openssl s_client` shows an expired notAfter dateExpired certificate
Fails only on one device or network, clock is visibly wrongClock skew
Fails only on a corporate network or with antivirus activeInterception proxy presenting an untrusted certificate

Already have the error code from a browser?

Chrome and other browsers translate most of the causes above into a specific error string. If you already have one, its own guide is faster than working from symptoms: ERR_SSL_PROTOCOL_ERROR covers failures before any certificate is even evaluated, ERR_CERT_DATE_INVALID covers the expired-certificate and clock-skew cases in detail, and ERR_SSL_VERSION_OR_CIPHER_MISMATCH covers the no-shared-cipher case with the exact server-side settings that cause it.

A handshake failure caught by openssl s_client today can still be a certificate that has weeks left before it expires, or a cipher suite that a server dropped in a routine hardening pass without anyone testing every client that connects to it. Running the SSL/TLS check with HostTracker's SSL/TLS check tool shows the same chain, protocol and verification result the commands above do, without needing a terminal open. HostTracker has monitored websites since 2004, checks from 300+ checkpoints in 158 cities, and can alert by email, SMS, voice call, Slack, Telegram and more before a handshake failure like this reaches a real visitor.

Frequently asked questions

Why does the handshake fail in one browser but not another?

Almost always a missing intermediate certificate. A browser that recently visited a different site signed by the same certificate authority has already cached the intermediate and can complete the chain itself, silently, while a client with no cached copy of it fails. The fix is on the server: send the full chain, not just the leaf certificate, so no client has to depend on already having cached the missing piece.

Is a handshake failure the same as a certificate error?

No. A certificate error means the handshake completed technically, the client and server agreed on how to talk, but the client rejected what the certificate itself said, an expired date or a wrong hostname. A handshake failure can happen before any certificate is even exchanged, purely from a version or cipher mismatch. openssl s_client shows which one occurred by how far the exchange got before it stopped.

Can a firewall cause a handshake to fail?

Yes, in two different ways. A firewall that blocks the port outright never lets a handshake start, and looks like a connection timeout rather than a TLS error. A firewall or middlebox that does a shallow inspection of the handshake itself can also reset the connection mid-negotiation if it does not recognize a newer TLS 1.3 feature, which looks exactly like a version mismatch from the client's side.

Does an old operating system matter, separately from an old browser?

Yes. Some browsers use the operating system's own TLS library and trust store rather than shipping their own, so an outdated OS can fail a handshake, or reject a certificate authority it does not yet trust, even with an otherwise current browser installed on top of it.

How do I check if it's my server or the visitor's device?

Run openssl s_client against your own domain from a completely different network. If it succeeds there and returns a clean verify code and a full certificate chain, the server side is configured correctly and the failure is specific to the visitor's device, network or software. If it fails from every location you try, the problem is on the server.

Vérifier maintenant

Lancez la vérification gratuite sur votre propre site, sans créer de compte.

SSL check

Surveiller en permanence

Soyez alerté dès que quelque chose casse : HostTracker vérifie depuis plus de 300 emplacements et vous prévient par e-mail, SMS, Slack, Telegram et plus encore.

Fonctionnalités HostTracker

Plus dans cette section: Corriger : guides pour les erreurs que l'on rencontre vraiment