ERR_SSL_PROTOCOL_ERROR means the browser reached the server, started the encrypted handshake, and got back something it could not use as TLS. The name resolved and the port answered; the failure is in the few milliseconds of negotiation before any page is requested.
Chrome shows it as "This site can't provide a secure connection" with the line "example.com sent an invalid response". Edge shows the same, since it shares Chrome's engine. Firefox reports the most common cause as SSL_ERROR_RX_RECORD_TOO_LONG, and Safari says it "can't establish a secure connection to the server".
Is it the site or your device?
That one question decides whether there is anything you can fix on the server.
Open the site on a second device, on a different network — a phone on mobile data is enough. Then run the domain through the SSL Checker, which connects from our server rather than your browser.
- It fails everywhere, and the SSL Checker reports a failed handshake: the server is the cause. Everything below about the server applies.
- It fails only on one device or one network: something between that device and the site is interfering. Skip to the visitor-side causes.
- It fails on every HTTPS site you open: the problem is entirely local — security software, a proxy, or a broken network.
What it is not
Certificate faults have their own error codes, and they are not this one. An expired certificate shows NET::ERR_CERT_DATE_INVALID; a certificate for the wrong name shows NET::ERR_CERT_COMMON_NAME_INVALID; a missing intermediate shows NET::ERR_CERT_AUTHORITY_INVALID on the devices that cannot complete the chain. Those all mean the handshake worked well enough for the browser to read a certificate and then reject it.
ERR_SSL_PROTOCOL_ERROR means it never got that far. That is why renewing the certificate — the first fix most guides suggest — rarely changes anything. The fault is in what the server says on port 443, not in the certificate file.
A server that speaks only TLS versions the browser no longer supports usually produces ERR_SSL_VERSION_OR_CIPHER_MISMATCH instead. It is worth knowing the difference, because the fix is different.
Server-side causes
Plain HTTP is answering on port 443
The most common cause by a distance. The web server is listening on port 443 but has not been told to speak TLS there, so it replies to the browser's encrypted greeting with an ordinary HTTP response. The browser receives readable text where it expected a handshake record, and gives up.
This is also exactly what Firefox's SSL_ERROR_RX_RECORD_TOO_LONG describes: the first bytes of an HTTP reply, read as a TLS record header, claim a record far larger than the protocol allows.
Confirm it from a terminal by asking for plain HTTP on the HTTPS port:
curl -v http://example.com:443/
If that returns an HTTP response with headers, the port is serving unencrypted HTTP. OpenSSL reports the same fault from the other direction:
openssl s_client -connect example.com:443 -servername example.com
An error containing wrong version number is the signature of this cause.
The fix is in the server configuration. In nginx the listener needs the ssl parameter, alongside a certificate and key:
listen 443 ssl;
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
listen 443; on its own serves plain HTTP. In Apache, the virtual host on port 443 needs SSLEngine on and the SSL module loaded. Reload the server after the change, then repeat the curl test — it should now fail, which is the correct result.
The hostname reaches a server block with no TLS for it
A server hosting many sites picks which certificate to present using SNI, the hostname the browser sends at the start of the handshake. If a newly added domain matches no configured HTTPS site, the request lands on the default one. Depending on how that default is set up, the browser gets the wrong certificate, a refused handshake, or plain HTTP — and only the last of those produces this error.
This is why the error so often appears for one domain on a server whose other sites work. Check that the domain, and its www form if it has one, appear in the HTTPS configuration and not only the port 80 one.
Something in front of the server breaks the handshake
A load balancer, firewall, or reverse proxy can end the handshake before your web server sees it. Two patterns account for most cases:
- A proxy-protocol mismatch. A listener configured to expect the proxy protocol header — sent by a load balancer to pass on the visitor's IP — reads the browser's handshake as a malformed header and drops it. It works through the load balancer and fails for anyone reaching the server directly, or the other way round.
- A security device closing the connection. An intrusion-prevention rule or rate limiter that cuts connections mid-handshake looks to the browser like an invalid response. If the error comes and goes, or appears under load, look here.
HTTPS is on a different port than the link says
A site served over TLS on port 8443, linked as https://example.com:443, or the reverse — an HTTP-only admin panel opened with https:// — produces the same mismatch as the first cause. Check the port in the address bar against the port the service actually uses for TLS.
If only one device or network sees it
When the site works everywhere else, the interference is local. In rough order of likelihood:
- Antivirus or firewall HTTPS scanning. Security software that inspects encrypted traffic sits in the middle of every handshake. When it mishandles one, the browser sees an invalid response. Turn off the HTTPS or web-scanning feature briefly and reload; if that fixes it, update the software or add an exception rather than leaving scanning off.
- A proxy or VPN. Corporate proxies and some VPNs intercept TLS the same way. Try with the VPN disconnected, or on a different network.
- A captive portal. Hotel and café Wi-Fi often intercepts traffic until you sign in to it. Open any plain
http://address to bring up the sign-in page. - An outdated browser or operating system. Old software can fail to negotiate with servers that have moved on to newer TLS settings. Update, then retry.
Clearing the browser cache rarely helps with this particular error, because nothing about a failed handshake is cached in the way a page is.
Diagnosing it in order
When the error is on your own site, this order finds the cause with the fewest steps:
- Run the SSL Checker. If it completes and shows a valid certificate and protocol, the server is fine and the cause is on the visitor's side.
- Run
curl -v http://yourdomain:443/. An HTTP response means plain HTTP is on the TLS port — fix the listener. - Run
openssl s_clientwith and without-servername. A difference between the two points at the SNI and server-block configuration. - Bypass anything in front. Connect to the origin's IP directly —
curl -v --resolve example.com:443:ORIGIN_IP https://example.com/— and compare with the public address. If one works and the other does not, the problem is in the layer between. - Read the server's error log at the moment of a failed request. A handshake failure is usually logged with a specific reason the browser never shows.
If the domain was recently moved to a new server, also confirm with the DNS Checker that its A record points where you think it does. A browser cannot show you a server's configuration if it is talking to a different server — an old host, or a parked page that was never set up for HTTPS.
Frequently asked questions
Can a visitor fix ERR_SSL_PROTOCOL_ERROR on someone else's site?
Only if the cause is on their side. If the site fails on every device and network, the owner has to fix the server, and telling them is the useful step.
Why does the site work in one browser and not another?
Browsers handle broken handshakes differently, and some security software inspects one browser's traffic but not another's. Check the site in a second browser on a second network before assuming the server is at fault.
Does a new SSL certificate fix it?
Rarely. A certificate problem gives a certificate error code. This error comes before the certificate is read, so it nearly always means the server's TLS configuration or the path to it is wrong.
Is it safe to continue to the site?
Browsers do not offer a way through this error, because no secure connection exists to continue on. That is the correct behaviour. Do not try to work around it with flags or older browsers.
Why did it start after I added a domain to my server?
The new domain is probably not in the HTTPS configuration, so its requests reach a default server block that does not handle TLS for it. Add the domain to the TLS site and reload.
Once the change is made, run the SSL Checker again. It reports the handshake as the server presents it now — protocol version, certificate, chain and hostname — which is the only version a visitor ever sees.