ERR_SSL_PROTOCOL_ERROR: what it means and how to fix it
Kofi Agyem, Founder and CEO, CloudzyroPublished · 5 min read
On this page
ERR_SSL_PROTOCOL_ERROR means the secure connection broke during setup. What causes it, fixes for visitors, and how site owners can test with openssl.
1. The short answer
ERR_SSL_PROTOCOL_ERROR means Chrome couldn't set up a secure HTTPS connection because the server's side of the handshake was broken. The server sent something that isn't valid TLS, or closed the connection mid-handshake. The single most common cause is a server answering plain HTTP on the HTTPS port.
As a visitor, check your clock, try another network and pause any antivirus HTTPS scanning. If it fails everywhere, the site's server needs fixing, and openssl s_client will show its owner exactly what's wrong. It's one of the This site can't be reached family, with its own heading.
2. What you'll see
- Chrome: This site can't provide a secure connection. example.com sent an invalid response. ERR_SSL_PROTOCOL_ERROR.
- Edge: Hmm... can't reach this page, with the same code.
- Firefox: Secure Connection Failed, often with SSL_ERROR_RX_RECORD_TOO_LONG when the server speaks plain HTTP on port 443.
- Safari: Safari can't open the page because Safari can't establish a secure connection to the server.
- curl: errors like
wrong version numberorunexpected eof while reading.
3. What causes it
On the server (the usual case):
- Plain HTTP on port 443. The server isn't set up for HTTPS, so it replies with an HTTP response that Chrome tries to read as TLS. In nginx, a
listen 443;withoutssldoes exactly this. - No certificate for that name, so the server aborts the handshake rather than sending one.
- Server Name Indication (SNI) not handled. A server hosting several sites that can't match the requested name may close the connection.
- Old or broken TLS settings, such as a server that only offers TLS 1.0 or 1.1. Chrome usually reports these as ERR_SSL_VERSION_OR_CIPHER_MISMATCH instead.
- A proxy or load balancer in front that's misconfigured for TLS.
On your side:
- Your system clock is wrong, which breaks certificate checks and can break the handshake.
- Antivirus or security software that inspects HTTPS traffic and mangles it.
- A VPN, proxy or captive portal (hotel or airport Wi-Fi) interfering with the connection.
- A saved HSTS policy that forces HTTPS for a site that doesn't support it, common with local development names.
4. Fixes for visitors, quickest first
- Reload, then try an incognito window to rule out extensions.
- Check your date, time and time zone are set automatically.
- Try another network. On public Wi-Fi, open any plain
http://site first to bring up the sign-in page, then try again. - Turn off your VPN or proxy.
- Pause your antivirus's HTTPS or web scanning to test. If that fixes it, update the software or add an exception.
- Clear browsing data for the site. On Windows, also open Internet Options, Content, and click Clear SSL state.
- Update Chrome and your operating system.
- If it's your own development site, open
chrome://net-internals/#hstsand delete the domain's security policy. This only removes policies the site set itself; names under preloaded endings like.appand.devalways require HTTPS.
If it still fails everywhere, the site's server is the problem and only the owner can fix it.
5. Fixes for site owners
- Test from outside with
openssl s_client(below).wrong version numberalmost always means plain HTTP on port 443. - Enable TLS on the HTTPS port. In nginx,
listen 443 ssl;withssl_certificateandssl_certificate_keyset. In Apache,SSLEngine onin the port 443 virtual host. - Make sure there's a certificate for every name the server answers, including
wwwand the bare domain. See www vs non-www. - Offer TLS 1.2 and TLS 1.3 with modern ciphers. Turn off SSL 3.0, TLS 1.0 and TLS 1.1, which RFC 8996 deprecated.
- Check every layer. If a CDN or load balancer terminates TLS, test both its address and the origin server.
- Don't force HTTPS until it works. An HSTS header with a long
max-agemakes browsers refuse plain HTTP for that time, so add it only once HTTPS is solid.
On Cloudzyro Sites & Apps, certificates and TLS settings are handled for you: a certificate is issued automatically once your domain's DNS points at us. If your own domain shows a TLS error while the site's cloudzyro.app address works, check its records: www as a CNAME to domains.cloudzyro.app, the bare domain as an A record to 173.234.137.167, and DNS only (gray cloud) if your DNS is at Cloudflare. The site's Domains tab says what it found.
6. A worked example
A developer sets up nginx for a new site and adds a server block for port 443. Chrome shows ERR_SSL_PROTOCOL_ERROR; Firefox shows SSL_ERROR_RX_RECORD_TOO_LONG.
openssl s_client -connect www.example.com:443 -servername www.example.comfails at once withwrong version number.curl -v http://www.example.com:443/returns a normal HTTP page. The HTTPS port is speaking plain HTTP.- The config says
listen 443;. They change it tolisten 443 ssl;, check the certificate paths, runsudo nginx -tand reload. - openssl now shows
TLSv1.3andVerify return code: 0 (ok), and the site loads in every browser.
7. How to check
# Try the handshake and show the certificate (macOS, Linux, Git Bash)
openssl s_client -connect www.example.com:443 -servername www.example.com
# Force a specific version, to see what the server supports
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
# Full detail of an HTTPS request (curl is built into Windows 10 and 11)
curl -v https://www.example.com/A working server prints the certificate chain, the protocol (TLSv1.3 or TLSv1.2) and Verify return code: 0 (ok). wrong version number means the port speaks plain HTTP. An immediate disconnect with no certificate usually means no certificate is set for that name, or SNI isn't handled. If the handshake works with -tls1_2 but fails with -tls1_3, or the other way round, look at the server's protocol settings.