Skip to main content
DevOpsintermediate

ERR_SSL_PROTOCOL_ERROR - How to Fix It

Fix ERR_SSL_PROTOCOL_ERROR in Chrome and Edge. Work out in one command whether the TLS handshake fails for everyone or only for you, then fix the right side of it.

8 min readUpdated August 2026

This site can't provide a secure connection example.com sent an invalid response. ERR_SSL_PROTOCOL_ERROR

ERR_SSL_PROTOCOL_ERROR means the TLS handshake failed before a single HTTP request was sent. Chrome and Edge use it as a catch-all, so the message itself tells you almost nothing - which is why the first step is a triage command rather than a fix.


Is This You or the Site?

Run one command from your machine:

openssl s_client -connect example.com:443 -servername example.com < /dev/null

Then repeat the test from a different network - a phone hotspot, or our SSL/TLS checker, which connects from outside your network entirely.

ResultMeaningGo to
Handshake fails everywhereThe server's TLS is misconfiguredSite-owner fixes
Handshake succeeds elsewhere, fails from your machineLocal interferenceVisitor-side fixes
Handshake succeeds everywhere, browser still errorsBrowser-level - cache, QUIC, or an extensionVisitor-side fixes

The -servername flag matters. It sends SNI, which is how a server hosting many sites on one IP knows which certificate to present. A handshake that succeeds without it and fails with it - or the reverse - is itself a diagnosis, pointing at a virtual host configuration problem.


Site-Owner Fixes

1. Confirm the port is actually speaking TLS

The most common cause is the least exotic: something is serving plain HTTP on port 443. This happens when a container, an application server or a load balancer sits behind the port without TLS configured.

# A TLS listener answers with a handshake; a plain HTTP server answers with text
curl -sv https://example.com 2>&1 | head -20
curl -s http://example.com:443 | head -5

If the second command returns HTML, port 443 is serving cleartext. Configure TLS on that listener, or terminate TLS at the proxy in front of it.

2. Check which TLS versions you offer

Browsers dropped TLS 1.0 and 1.1 in 2020. A server offering only those versions is unreachable from any current browser.

openssl s_client -tls1_2 -connect example.com:443 -servername example.com < /dev/null
openssl s_client -tls1_3 -connect example.com:443 -servername example.com < /dev/null

At least one must succeed. For nginx:

ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;

Then reload:

sudo nginx -t && sudo systemctl reload nginx

3. Check the certificate and key match

A certificate paired with the wrong private key fails the handshake. Compare the moduli - they must be identical:

openssl x509 -noout -modulus -in /etc/ssl/certs/example.com.crt | openssl md5
openssl rsa  -noout -modulus -in /etc/ssl/private/example.com.key | openssl md5

4. Check SNI and virtual hosts

When one IP serves several sites, a request for a hostname with no matching server block falls through to a default that may not have TLS configured. Test each hostname explicitly with -servername, and confirm every HTTPS virtual host has its own ssl_certificate directive.

Advertisement

5. Read the server's error log

The server usually records the reason the handshake failed:

sudo tail -n 50 /var/log/nginx/error.log
sudo journalctl -u nginx --since "10 minutes ago"

Visitor-Side Fixes

If the handshake succeeds from other networks, work through these in order.

1. Test without your security software

Antivirus products and corporate proxies that inspect HTTPS terminate and re-establish TLS. An outdated or buggy one fails the handshake outright. Temporarily disable HTTPS scanning or SSL/TLS filtering and reload.

If that fixes it, update the product rather than leaving inspection off permanently - and on a managed device, report it to IT rather than working around it.

2. Disable QUIC as a test

Chrome uses QUIC over UDP for HTTP/3, and some middleboxes handle it poorly.

Go to chrome://flags/#enable-quic, set it to Disabled, and restart the browser. If the site now loads, the network path is the real problem - the flag is a diagnostic, not a permanent fix.

3. Clear the browser's SSL state

Cached handshake decisions survive a normal reload. In Chrome and Edge, clear Cached images and files for All time, then restart the browser. On Windows you can also clear the system SSL cache through Internet Options > Content > Clear SSL state.

4. Check the system clock

w32tm /resync
timedatectl status   # Linux
sudo sntp -sS time.apple.com   # macOS

Set the clock to the correct time. Never set a false date to work around a TLS or certificate error - doing so disables validity checking for every site you visit afterwards.

5. Test in a clean profile

Extensions - particularly VPN, proxy and privacy extensions - can break TLS. Open an incognito window with extensions disabled, or create a fresh browser profile.

What not to do

Do not look for a way to re-enable TLS 1.0 or 1.1. Browsers removed them because they are broken, the removal is not configurable in current versions, and a site that requires them needs its server fixed. Do not disable certificate or protocol validation to force a connection - a handshake that fails may be failing for a good reason.


Verify the Fix

# Full handshake detail, including negotiated version and cipher
openssl s_client -connect example.com:443 -servername example.com < /dev/null 2>/dev/null | grep -E "Protocol|Cipher|Verify return code"

# End to end
curl -sI https://example.com | head -1

You want a negotiated protocol of TLSv1.2 or TLSv1.3, Verify return code: 0 (ok), and an HTTP status line from curl. Confirm from a second network, and in a browser profile that has never loaded the site.


Prevention

  • Pin your TLS configuration to a maintained baseline - Mozilla's intermediate profile is the usual reference - and review it when you upgrade the server.
  • Test TLS from outside your network on a schedule, not only after a report. A configuration that works from inside can be broken for everyone else.
  • Include a handshake check in deployment smoke tests. openssl s_client in a pipeline catches a broken certificate deployment before users do.
  • Automate certificate renewal, and verify the reload actually happened - a renewed certificate that was never loaded is a common cause of a sudden handshake failure.
  • Keep at least TLS 1.2 enabled while TLS 1.3 rolls out, so older but still supported clients are not stranded.

Frequently Asked Questions

Find answers to common questions

The TLS handshake failed before any HTTP request was sent. The browser and the server could not agree on how to establish an encrypted connection. It is deliberately vague - Chrome uses it as a catch-all for handshake failures that have no more specific code.

Run 'openssl s_client -connect example.com:443 -servername example.com'. If the handshake fails from a machine on a different network too, the server is misconfigured. If it succeeds elsewhere but not on your machine, something local is interfering.

Serving plain HTTP on port 443. If the application, container or load balancer behind the port is not doing TLS at all, the browser's handshake gets an HTTP response and fails immediately. It is far more common than an exotic cipher problem.

Yes. Products that inspect HTTPS terminate and re-establish TLS, and a buggy or outdated one fails the handshake. Temporarily disabling HTTPS scanning is a legitimate diagnostic step, though leaving it off permanently is a real tradeoff.

Yes, but set it correctly rather than changing it to make an error disappear. A badly wrong clock breaks handshakes and certificate validation together. Sync it with your time server; never set a false date to bypass a warning.

The two ship different TLS stacks and different minimum versions. A server offering only TLS 1.0 or 1.1, or an unusual cipher list, can satisfy one and not the other. This almost always points at an outdated server configuration.

QUIC is a UDP-based transport Chrome uses for HTTP/3. Some middleboxes handle it poorly, which surfaces as handshake errors. Turning it off at chrome://flags/#enable-quic is a useful diagnostic; if it fixes the problem, the network path is the real culprit.

No. TLS 1.0 and 1.1 were removed from browsers because they are broken, and browsers no longer offer a way back. If a site needs them, the server must be updated - there is no safe client-side workaround.

Test each explicitly with openssl: 'openssl s_client -tls1_2 -connect example.com:443' and again with -tls1_3. Whichever versions complete a handshake are the ones your server offers.

The mismatch error is specific: no shared protocol version or cipher suite. ERR_SSL_PROTOCOL_ERROR is the general case, covering malformed responses, non-TLS traffic on the port, and interference. A mismatch error gives you a narrower place to look.