Getting curl 92 HTTP/2 stream 1 was not closed cleanly INTERNAL_ERROR err 2
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
curl: (92) HTTP/2 stream 1 was not closed cleanly: INTERNAL_ERROR usually means the HTTP/2 conversation broke at the server side or at some proxy layer between client and server. The important detail is that curl is often only reporting the protocol failure it observed, not proving that the client was wrong. The fastest way to debug it is to separate three possibilities: client bug, server or proxy HTTP/2 bug, or a transport issue that only surfaces under HTTP/2.
What the Error Usually Means
HTTP/2 uses streams inside a single connection. Stream 1 is typically the first request stream. “Not closed cleanly” means the stream ended abnormally instead of following the expected protocol shutdown sequence.
In practice, common causes include:
- buggy server-side HTTP/2 implementation
- reverse proxy or CDN issue
- TLS or ALPN negotiation oddities
- server resource exhaustion or request cancellation
- old
curlor TLS library behavior
The “INTERNAL_ERROR” part is generic. It points to failure, not root cause.
Start with a Verbose Request
First, capture more detail:
If you need even more protocol detail:
This helps answer basic questions:
- was HTTP/2 actually negotiated
- did TLS succeed
- did headers arrive before failure
- is the failure repeatable on every request
Without that baseline, you are mostly guessing.
Force HTTP/1.1 as a Diagnostic Step
One of the best tests is to bypass HTTP/2 entirely.
If HTTP/1.1 works but HTTP/2 fails, the problem is very likely in HTTP/2 handling on the server, proxy, load balancer, or CDN path. That does not permanently solve the problem, but it isolates the layer quickly.
This is often the most useful first distinction.
Update curl and TLS Dependencies
Older curl builds, especially when linked against older TLS or HTTP/2 libraries, can trigger protocol issues that newer versions handle better.
Check your version:
You want to see the linked libraries too, such as OpenSSL, LibreSSL, or nghttp2. If the environment is old, updating curl is a reasonable early step before blaming the server entirely.
Check Whether a Proxy or CDN Is Involved
Many “server” failures actually happen in intermediaries:
- nginx reverse proxy
- Apache front-end
- Envoy or ingress controller
- Cloudflare or another CDN
- corporate outbound proxy
If the request path includes any of those layers, test directly against the origin if possible. If the origin works and the public hostname fails, you have narrowed the issue to the intermediary.
Retry with a Smaller or Simpler Request
Some HTTP/2 issues appear only with certain payload sizes, headers, or response streaming patterns.
For example:
If a small health endpoint works but a large download fails, the problem may relate to response buffering, compression, or stream handling under load rather than basic connectivity.
Server-Side Clues Matter More Than Client-Side Guessing
If you control the server, inspect:
- reverse proxy error logs
- HTTP/2 configuration
- upstream timeouts
- memory and CPU pressure
- response compression settings
A generic stream error from curl is often downstream evidence of something the server logs will describe much more specifically.
Temporary Workaround
If you need an immediate operational workaround while the server issue is being fixed, forcing HTTP/1.1 is reasonable:
But treat that as a mitigation, not a root-cause resolution. If the endpoint is supposed to support HTTP/2, the underlying issue is still there.
Example Diagnostic Sequence
A practical sequence is:
- run
curl -v - test
curl --http1.1 - compare another client such as a browser or different machine
- inspect server or proxy logs
- update
curlif the client stack is old
This usually tells you whether to focus on the client environment or the remote infrastructure.
Common Pitfalls
The biggest mistake is assuming the error automatically means curl is broken. Another is treating “INTERNAL_ERROR” as a precise diagnosis when it is only a generic HTTP/2 failure signal. Developers also often skip the simplest and most informative test, which is forcing HTTP/1.1 to see whether the issue is specifically tied to HTTP/2. Finally, if a CDN or reverse proxy is present, debugging only the origin server can waste time because the failure may not be happening there.
Summary
- '
curl 92with HTTP/2 usually points to a server-side or intermediary protocol problem.' - Start with
curl -vand confirm whether HTTP/2 was actually negotiated. - Test
--http1.1to determine whether the issue is specific to HTTP/2. - Check proxies, CDNs, ingress layers, and server logs if you control the stack.
- Updating
curlcan help, but it is often only part of the story rather than the full fix.

