Error guide

SSL/TLS handshake failed

An SSL handshake failed or TLS handshake failure means the TCP connection succeeded and the TLS negotiation on top of it did not.

An SSL handshake failed error, also reported as a TLS handshake failure or SSL handshake error, means the client connected to the server successfully and the two could not agree on a secure session. The TCP layer worked; TLS did not. The distinction matters, because it rules out firewalls, routing and dead processes immediately — something is definitely listening and definitely answering.

The causes divide into a few families. No shared protocol version or cipher suite, which is increasingly common as clients drop older TLS versions. A certificate problem — expired, wrong hostname, or an incomplete chain the client cannot verify. An SNI mismatch, where the server has several certificates and cannot tell which one to present. And client certificate requirements, where the server demands one and the client has none.

The incomplete-chain case is worth calling out because it hides. Browsers often fetch missing intermediates themselves, so a site with a broken chain works in a browser and fails for curl, for API clients and for monitoring — an outage that only affects programmatic traffic while looking entirely healthy to the person checking it.

The handshake failure message each common client prints, and what it usually points to.
MessageWhere you see itWhat it usually means
ERR_SSL_VERSION_OR_CIPHER_MISMATCHChrome, EdgeNo shared TLS version or cipher suite, often an outdated server or no certificate configured for this hostname.
ERR_SSL_PROTOCOL_ERRORChrome, EdgeThe server answered with something that is not valid TLS: plain HTTP on port 443, a proxy in the way, or a broken listener.
SSL_ERROR_NO_CYPHER_OVERLAPFirefoxClient and server have no cipher suite in common, usually after a hardening change on one side.
sslv3 alert handshake failurecurl (35), OpenSSLThe server ended the handshake with a fatal alert: a version, cipher or SNI mismatch, or a client certificate it requires.
unable to get local issuer certificatecurl (60), OpenSSLThe chain is incomplete, or the issuing CA is not in this client's trust store.
PKIX path building failedJava (SSLHandshakeException)Java cannot build a path to a trusted root: a missing intermediate, or a CA missing from the JVM trust store.
CERTIFICATE_VERIFY_FAILEDPython (ssl, requests)Verification failed: a missing intermediate, an expired or self-signed certificate, or an outdated CA bundle.
unable to verify the first certificateNode.jsThe server sent its own certificate without the intermediates, which Node does not fetch on its own.
remote error: tls: handshake failureGoThe server rejected the handshake with an alert. Same causes as the OpenSSL alert above.
Error 525: SSL handshake failedCloudflareCloudflare reached your origin and the TLS handshake between Cloudflare and the origin failed.

Common causes

  • No overlapping TLS version between client and server, typically an old server meeting a modern client.
  • No shared cipher suite after a security hardening change on either side.
  • A certificate that does not cover the requested hostname.
  • An incomplete chain missing intermediate certificates.
  • An SNI mismatch on a server hosting multiple certificates.
  • The server requiring a client certificate the client does not present.
  • An expired certificate, which fails the handshake as a specific case.

How to diagnose it

  1. Run openssl s_client -connect host:443 -servername host and read the handshake output: it names the protocol, the cipher and the chain.
  2. Check the returned chain for missing intermediates — this is the failure that works in browsers and nowhere else.
  3. Confirm the certificate's subject alternative names include the exact hostname being requested.
  4. Test a specific TLS version explicitly to find out whether version negotiation is the problem.
  5. Test with and without SNI if the server hosts multiple sites on one address.

Whose fault is it? The server's side

Usually server-side — configuration or certificate. It can be the client where an old client cannot negotiate with a properly hardened server, in which case the client is the thing that has to move.

What monitoring sees

A handshake failure fails a check, but a garbled handshake is also what a broken network path looks like, so Uptimely checks its own path first: before one takes a monitor down, the worker confirms it can reach known-good sites over the same route, and discards the check as inconclusive if it cannot. Certificate problems are a clearer signal. Uptimely's SSL Certificate monitor reads the live handshake, so chain and expiry problems are visible from the same place the outage would be, and an incomplete chain is caught before it is discovered by an API client.

Uptimely's SSL Certificate monitor reads the certificate from the live handshake, the same one an API client gets, so a broken chain or an expired certificate fails a check where you can see it.

Start monitoring free →

Questions

What is the difference between SSL handshake failed, TLS handshake failure and SSL handshake error?

None in practice. SSL is the old name for the protocol, and every modern connection actually uses TLS. Many tools still say SSL for historical reasons, OpenSSL's sslv3 alert among them, so all three messages have the same causes and the same fixes. A message such as peer failed to perform TLS handshake says the same thing in a library's own words: the connection was made and no secure session came out of it.

Can an SSL handshake failure be caused by the client?

Yes. An old client that cannot speak TLS 1.2 or 1.3, an outdated CA bundle, a wrong system clock that makes a valid certificate look expired or not yet valid, and antivirus or corporate proxies that intercept TLS all fail the handshake from the client side.

Which TLS versions should a server support?

TLS 1.2 and TLS 1.3. TLS 1.0 and 1.1 were formally deprecated by RFC 8996 in 2021 and current browsers refuse them, while SSLv2 and SSLv3 are broken. A server that only offers the old versions fails the handshake with every modern client.

Why does my site work in a browser but fail for curl and monitoring?

Almost always an incomplete certificate chain, the one SSL handshake failure that hides. Browsers fetch missing intermediates on their own; curl, API clients and monitors do not. Installing the full chain on the server fixes it for everything.

How do I debug an SSL or TLS handshake failed error?

openssl s_client -connect host:443 -servername host prints the negotiated protocol, the cipher and the certificate chain the server actually returned, which identifies almost every cause in one command.

One of the Uptimely HTTP and network error guides, written for the person who operates the server rather than the one refreshing the page. Something here read wrong to you? Email support@getuptimely.com.