Skip to content
RU

ERR_SSL_PROTOCOL_ERROR: How to Fix "Sent an Invalid Response"

Monitor with a blurred white browser error page and warning icon, server tower beside it

What it means: Chrome started a TLS handshake, but the server's reply was not valid TLS, so the connection was dropped.

  1. Reload in an incognito window, then another browser.
  2. Turn off antivirus HTTPS scanning, VPN and proxies.
  3. Fails on every network? Tell the site owner.
  4. Owner: check port 443 speaks TLS, not plain HTTP.

Test your URL now

Runs a full TLS check: handshake, protocol versions, certificate chain, trust and expiry.

Check your site's SSL →

What ERR_SSL_PROTOCOL_ERROR means

ERR_SSL_PROTOCOL_ERROR is Chromium net error -107, described in the source as “An SSL protocol error occurred.” It is a catch-all: when BoringSSL, Chrome's TLS library, aborts a handshake for a reason that has no dedicated Chrome code, Chrome's error mapping falls back to ERR_SSL_PROTOCOL_ERROR. The error page reads “This site can't provide a secure connection” followed by “host sent an invalid response.”

The failure sits at the TLS layer. DNS resolved and the TCP connection opened, but the bytes that came back were not a TLS handshake Chrome could accept. It is not a certificate problem (those are ERR_CERT_* codes on a “Your connection is not private” page), not a wrong system clock (that gives ERR_CERT_DATE_INVALID), and usually not a version or cipher disagreement: Chrome maps “no common TLS version or cipher” to ERR_SSL_VERSION_OR_CIPHER_MISMATCH. A server that only speaks TLS 1.0 or 1.1 therefore produces the mismatch error, not this one.

Causes in Chrome, Edge, Firefox and Safari

BrowserWhat you seeMost common trigger
Chrome, Edge, Brave, OperaERR_SSL_PROTOCOL_ERROR, “sent an invalid response”Plain HTTP answering on an https:// URL or port
FirefoxSSL_ERROR_RX_RECORD_TOO_LONG for the plain-HTTP case; other handshake faults get their own NSS codesSame server-side fault, reported by NSS
Safari“Safari can't establish a secure connection to the server”, no codeSame server-side fault

The triggers that actually produce this code, roughly from most to least common:

  • Plain HTTP where TLS is expected. An nginx listen 443; without ssl, a Docker mapping like 443:80, a load balancer forwarding 443 to an HTTP backend, or https:// typed for a dev server that only speaks HTTP. The server answers the ClientHello with an HTTP 400 page, which cannot be parsed as a TLS record.
  • HSTS forcing https onto an HTTP-only port. HSTS covers every port of a host. Once a domain, or a preloaded TLD such as .dev or .app, has HSTS, http://host:8080 is rewritten to https://host:8080; if that port speaks HTTP, you get this error.
  • Renegotiation Chrome refuses. Chrome accepts a server-initiated TLS 1.2 renegotiation only on HTTP/1.1 connections. A server that asks for a client certificate mid-connection over HTTP/2, or under TLS 1.3, which has no renegotiation at all, gets the connection aborted.
  • Broken TLS interception. Antivirus HTTPS scanning, corporate inspection proxies and some VPN clients terminate TLS themselves; a buggy one sends malformed handshake messages.
  • Non-compliant TLS stacks on embedded devices, old appliances or custom code that send malformed or out-of-order handshake messages.

Two things that look related but are not: HTTP/3 failures run over QUIC and carry their own codes such as ERR_QUIC_PROTOCOL_ERROR, so disabling QUIC does not fix this error. And middleboxes that choke on the larger post-quantum ClientHello Chrome has sent since version 124 typically cause dropped or reset connections (ERR_CONNECTION_RESET), not this code.

Behind Cloudflare, nginx or another proxy

The browser's TLS session ends at the first TLS terminator, so this error is about that hop. Origin TLS failures behind Cloudflare appear as Cloudflare 525 or 526 pages, not as ERR_SSL_PROTOCOL_ERROR.

nginx

server {
    listen 443 ssl;          # without "ssl" this port answers in plain HTTP
    listen [::]:443 ssl;     # the IPv6 line needs "ssl" too
    http2 on;                # nginx 1.25.1+; older: listen 443 ssl http2;
    server_name example.com www.example.com;

    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_protocols       TLSv1.2 TLSv1.3;
}

A classic partial outage: listen 443 ssl; is correct but listen [::]:443; lacks ssl. Visitors who reach the site over IPv4 are fine; everyone with working IPv6 gets ERR_SSL_PROTOCOL_ERROR.

Cloudflare

With the DNS record proxied (orange cloud), Cloudflare terminates TLS at its edge, so a misconfigured origin port cannot produce this code in the browser. It can appear when the record is DNS only (grey cloud) or Cloudflare is paused: browsers then connect straight to your origin, which must serve real TLS on 443 itself.

HAProxy and load balancers

A TCP-mode frontend on 443 that forwards to an HTTP backend produces the plain-HTTP symptom exactly. Either terminate TLS on the frontend (bind :443 ssl crt /etc/haproxy/certs/example.pem) or make sure the backend itself speaks TLS.

If you own the site

  1. See what the port really returns.
    curl -sv https://example.com/ -o /dev/null
    # "wrong version number" in the TLS error = the port answered in plain HTTP
    curl -si http://example.com:443/ | head -1
    # an HTTP status line here confirms it
  2. Run a handshake by hand, with SNI: openssl s_client -connect example.com:443 -servername example.com -brief </dev/null. A healthy server prints the protocol version and cipher; garbage or an immediate error points at the listener. Repeat against the IPv6 address with -connect '[2001:db8::10]:443'.
  3. Fix the listener: add ssl to every listen on 443, then nginx -t && systemctl reload nginx. In Docker, docker ps must not show 0.0.0.0:443->80/tcp unless the container terminates TLS on 80.
  4. Request client certificates at handshake time, not per path. Mid-connection client-certificate requests rely on renegotiation, which Chrome refuses on HTTP/2 and TLS 1.3.
  5. Still unclear? Capture a NetLog. Open chrome://net-export, reproduce the error, stop logging and look for the SSL_HANDSHAKE_ERROR event: it records the underlying BoringSSL error reason that ERR_SSL_PROTOCOL_ERROR hides.

If you are a visitor

  • Isolate the browser: try an incognito window (extensions off) and a second browser. If only one Chrome profile fails, an extension or a proxy setting is involved.
  • Isolate the network: switch to mobile data. If the site works there, something on the original network is intercepting TLS: a corporate proxy, router, VPN or filtering DNS.
  • Antivirus HTTPS scanning: temporarily turn off the web or HTTPS scanning feature and retry; if that fixes it, update the product or exclude the site.
  • Restart the browser fully. This drops pooled sockets and cached TLS sessions; chrome://net-internals/#sockets offers “Flush socket pools” for the same effect.
  • Local dev hosts only: if localhost or your own test domain is being forced to https, delete its entry at chrome://net-internals/#hsts.

Clearing the cache and cookies does not help: certificates and handshakes are not stored in the HTTP cache. A wrong system clock is not the cause either. If the error appears on every network, device and browser, the fault is on the server and only the site owner can fix it.

How to confirm the fix

openssl s_client -connect example.com:443 -servername example.com -brief </dev/null
# CONNECTION ESTABLISHED
# Protocol version: TLSv1.3
curl -sI https://example.com/ | head -1
# HTTP/2 200

Run both over IPv4 and IPv6 (curl -4, curl -6) if the site has an AAAA record. To check the handshake, protocol versions and certificate from outside your network, run the domain through the SSL/TLS checker.

Related errors

CertificateExpiry, issuer, domains (SAN)
ChainIntermediate and root CA validation
TLS ProtocolTLS version and cipher suite
VulnerabilitiesHeartbleed, POODLE, weak ciphers

Why teams trust us

TLS 1.3
supported
Full
CA chain check
3,158
checks in 30 days
30/14/7
days-to-expiry alerts

How it works

1

Enter domain

2

TLS chain verified

3

Expiry date & vulnerabilities

What Does the SSL Check Cover?

SSL/TLS is the encryption protocol that protects data between the browser and server. Our tool analyzes the certificate, chain of trust, TLS version, and knownvulnerabilities.

Certificate Details

Issuer, validity period, signature algorithm, covered domains (SAN), and validation type (DV/OV/EV).

Chain of Trust

Full chain verification: from leaf certificate through intermediates to root CA.

TLS Analysis

Protocol version (TLS 1.2/1.3), cipher suites, Perfect Forward Secrecy (PFS) support.

Expiry Alerts

Set up a monitor — get Telegram and email alerts 30/14/7 days before expiration.

DV vs OV vs EV Certificates

DV (Domain Validation)
  • Confirms domain ownership only
  • Issued in minutes automatically
  • Free via Let's Encrypt
  • Suitable for most websites
  • Most common certificate type
OV / EV
  • Organization (OV) or Extended Validation (EV)
  • Issued in 1-5 business days
  • Costs $50 to $500/year
  • For finance, e-commerce, government sites
  • Increases user trust

Who uses this

DevOps

SSL certificate monitoring

Security

TLS config audit

SEO

HTTPS as ranking factor

E-commerce

customer trust

Common Mistakes

Expired certificateBrowsers block sites with expired SSL. Set up auto-renewal or monitoring.
Incomplete certificate chainWithout intermediate CA, some browsers and bots cannot verify the certificate.
Mixed content on HTTPS siteHTTP resources on an HTTPS page — the browser lock icon disappears, reducing trust.
Using TLS 1.0/1.1Legacy TLS versions have known vulnerabilities. Use TLS 1.2+ or 1.3.
Domain mismatch in certificateThe certificate must cover all site domains, including www and subdomains.

Best Practices

Set up auto-renewalLet's Encrypt + certbot with cron — certificate renews automatically every 60-90 days.
Enable HSTSStrict-Transport-Security header forces browsers to always use HTTPS.
Use TLS 1.3TLS 1.3 is faster (1-RTT handshake) and safer — legacy ciphers removed.
Monitor expiration datesCreate a monitor on Enterno.io — get notified well before expiration.
Verify chain after renewalAfter certificate renewal, confirm that intermediate certificates are installed.

Get more with a free account

SSL certificate monitoring, check history and alerts 30 days before expiry.

Sign up free

Learn more

Sources

Frequently Asked Questions

Is it safe to bypass ERR_SSL_PROTOCOL_ERROR?

There is nothing to bypass: no secure connection was established, so Chrome offers no Proceed link. Typing thisisunsafe, an undocumented Chrome bypass that may change, only works on certificate warning pages, not on this error.

Why do I get it on localhost or a dev port such as :8080?

HSTS covers every port of a host, and preloaded TLDs such as .dev and .app are HTTPS-only, so the browser sends TLS to a port that speaks plain HTTP. For your own dev host, delete its entry at chrome://net-internals/#hsts or serve TLS on that port.

Why does it fail only on one network or one device?

Something on that path is intercepting TLS: a corporate proxy, antivirus HTTPS scanning, a VPN client or router filtering. It can also be IPv6: if the IPv6 listener lacks TLS, only devices with working IPv6 fail.

Why does Chrome show it while Firefox shows a different error?

Each browser names the failure in its own words. For plain HTTP on port 443, Firefox reports SSL_ERROR_RX_RECORD_TOO_LONG and Safari says it cannot establish a secure connection; the server fix is the same.

Can a wrong system clock or an expired certificate cause ERR_SSL_PROTOCOL_ERROR?

Not normally. Date problems show up as ERR_CERT_DATE_INVALID on a privacy warning page. ERR_SSL_PROTOCOL_ERROR means the handshake itself broke before certificate checks mattered.

Try the live tool that powered this guide

Free plan — 10 monitors, checks every 5 min, no card required. Upgrade for 1-minute interval and multi-region monitoring.