sfw/fix
ERR_HTTP2_PROTOCOL_ERROR high

ERR_HTTP2_PROTOCOL_ERROR in Chrome

Chrome kills the connection after the server sends a malformed or non-compliant HTTP/2 response.

What you see

This site can't be reached
The webpage at https://example.com/ might be
temporarily down or it may have moved.
ERR_HTTP2_PROTOCOL_ERROR

What’s actually happening

Chrome and Edge fail; Firefox or curl over HTTP/1.1 often load the same URL fine. It frequently hits one endpoint — a download, an API route, a large response — rather than the whole site. Reloads are inconsistent. chrome://net-export or the DevTools Network panel will show the stream reset right after headers or partway through the body.

Common causes

  • The server emits a Content-Length that disagrees with the bytes actually sent, or mangles chunked/gzip framing — illegal under HTTP/2's stricter rules.
  • A buggy or old HTTP/2 implementation (an outdated nginx/Apache module, a misbehaving load balancer or app server) sending non-compliant frames.
  • Intercepting antivirus or a corporate MITM proxy (Kaspersky, ESET, some Zscaler setups) rewriting traffic and breaking framing.
  • The server sends headers HTTP/2 forbids — e.g. Connection: keep-alive or other hop-by-hop headers that are illegal in h2.
  • Oversized response headers blowing the peer's HPACK/header-list limit, causing a stream or connection reset.

How to fix it

  1. Isolate the layer with curlRun curl -v --http2 https://url and curl -v --http1.1 https://url. If h2 fails and 1.1 works, the server's HTTP/2 output is malformed — that's your target. Capture the full picture with chrome://net-export (Network events) and load it in netlog-viewer.
  2. Fix Content-Length / framingMake sure your app sets a correct Content-Length or uses chunked encoding properly — not both, and never a wrong length. A reverse proxy buffering responses (proxy_buffering on in nginx) can paper over a flaky upstream while you fix the real cause.
  3. Strip illegal h2 headersRemove hop-by-hop headers (Connection, Keep-Alive, Transfer-Encoding, Upgrade) from responses your app or proxy emits — HTTP/2 rejects them. Check any custom middleware adding headers.
  4. Rule out client interceptionReproduce in Chrome Incognito with extensions off, and temporarily disable HTTPS/SSL scanning in local antivirus. If that fixes it, the MITM proxy is corrupting frames — fix or exclude the domain there.
  5. Update or bypass the h2 stackPatch nginx/Apache/your LB to a current version. As a temporary mitigation you can disable HTTP/2 on the vhost (remove http2 from listen in nginx) so clients fall back to 1.1 while you ship the real fix.

Stop it recurring

Keep your HTTP/2 server/proxy patched and never emit hop-by-hop headers or a Content-Length that doesn't match the body.

Related errors