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
- 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.
- 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.
- 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.
- 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.
- 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