ERR_SSL_PROTOCOL_ERROR / SSL_ERROR_RX_RECORD_TOO_LONG: what it means and how to fix it

The browser reports a mysterious SSL protocol error before any certificate page appears. The client spoke TLS; whatever answered did not speak TLS back cleanly.

What you see

“Record too long” often means the client expected a TLS record and instead got an HTTP response line such as HTTP/1.1 200 OK — those ASCII bytes look like an impossibly long TLS record.

Common causes

CauseWhat is going wrongFix
HTTPS to an HTTP portYou open https://host:8080 but 8080 speaks plain HTTPUse http:// or terminate TLS on that port
Wrong port in generalApp on 3000, you hit 443 or vice versaMatch scheme and port to what actually listens
Proxy “flexible” / off TLS to originEdge speaks HTTPS to visitors but connects to origin with HTTP while the client or a tool expects TLS end-to-endUse full TLS to the origin (strict) when the origin has a real certificate; keep schemes consistent
TLS version mismatchServer only TLS 1.3, ancient client only 1.0 (or the reverse with a broken appliance)Modernise server and client; avoid forcing tiny TLS ranges
Antivirus / corporate HTTPS scanningMITM appliance presents a broken or unexpected handshakeTest another network; install the corp root only if you trust IT; exclude the host from scanning for local dev
Captive portal / hotel Wi‑FiGateway injects an HTTP login page into an HTTPS requestComplete the portal login on HTTP first
Corrupt middlebox or HTTP/2 confusionLoad balancer sends cleartext where TLS was expectedCheck backend protocol (h2c vs TLS) on the proxy

Diagnose with curl and openssl

# See the handshake (or the plaintext surprise)
curl -vI https://example.com/ 2>&1 | sed -n '1,40p'

# Low-level TLS talk; look for "Certificate chain" vs an HTTP banner
openssl s_client -connect example.com:443 -servername example.com </dev/null

# If you suspect plain HTTP on 443:
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>&1 | head
# or:  curl -v http://example.com:443/ 

If openssl s_client prints an HTTP status line or HTML instead of a certificate chain, the port is not speaking TLS. If handshake works but the name is wrong, that is ERR_CERT_COMMON_NAME_INVALID; if the dates are wrong, see certificate has expired; if the chain is incomplete, see unable to get local issuer certificate.

CDN / reverse-proxy SSL modes

Many CDNs offer a mode where browsers use HTTPS to the edge, but the edge fetches your origin over plain HTTP. That can be fine for static sites when configured deliberately, but tools that connect directly to the origin with HTTPS, or origins that redirect HTTP→HTTPS incorrectly, produce protocol errors and redirect loops. Prefer end-to-end TLS to the origin when the origin has a valid certificate, and keep redirects consistent (see ERR_TOO_MANY_REDIRECTS and Mixed Content).

Related

Cloudflare Error 525 · Cloudflare Error 526 · SSL wrong version number · ERR_CERT_COMMON_NAME_INVALID · Certificate has expired · unable to get local issuer certificate · Mixed Content blocked · ERR_NAME_NOT_RESOLVED · ERR_TOO_MANY_REDIRECTS

Questions

What does ERR_SSL_PROTOCOL_ERROR mean?

The browser started a TLS handshake and the other side's bytes were not valid TLS — often plain HTTP on a port you called with https://.

What is SSL_ERROR_RX_RECORD_TOO_LONG?

Firefox's way of saying it expected a TLS record and got something else (frequently an HTTP response). Same class of problem as Chrome's ERR_SSL_PROTOCOL_ERROR.

How do I check with openssl?

Run openssl s_client -connect host:443 -servername host and see whether you get a certificate chain or an HTTP banner.

Can antivirus cause this?

Yes. HTTPS scanning middleboxes sometimes break handshakes. Try another network or temporarily disable HTTPS scanning on your own machine to test.

Is this the same as a certificate name mismatch?

No. Name mismatch and expiry happen after a TLS handshake succeeds. Protocol errors happen during the handshake itself.

Published .

Try it

Related guides

Newest guides