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.
| Result | Meaning | Go to |
|---|---|---|
| Handshake fails everywhere | The server's TLS is misconfigured | Site-owner fixes |
| Handshake succeeds elsewhere, fails from your machine | Local interference | Visitor-side fixes |
| Handshake succeeds everywhere, browser still errors | Browser-level - cache, QUIC, or an extension | Visitor-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.
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_clientin 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.