You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[Bug]: JS SDK: one HTTP/2 GOAWAY (ENHANCE_YOUR_CALM) from the sandbox.e2b.app edge permanently breaks files.write process-wide; undici 8.8.0 never recovers the session #1641
e2b (JS SDK) 2.38.0, Node 22.23.2 on Linux (Fly.io) and Node 23.6.0 on macOS 14. loadUndici selects the undici8 optional dependency, which resolves to undici 8.8.0.
Timestamp of the issue
First seen 2026-08-04 00:42 UTC; cause chains captured 2026-08-04 14:29 UTC.
Frequency
Happens every time
Expected behavior
When the server ends an HTTP/2 session (GOAWAY), the cost should be at most the in-flight requests. The SDK (or undici underneath it) should open a fresh connection for subsequent requests, and ideally retry streams the server refused, per RFC 9113 §8.7.
every subsequent files.write in the process fails with NGHTTP2_INTERNAL_ERROR, including immediate retries, across all sandboxes, until the process restarts. Filesystem calls that go through the connect-RPC transport (files.makeDir) keep working on the same sandbox at the same moment, because that transport uses a separate dispatcher.
This took our chat product down: since 2.25.0 all sandboxes' envd traffic shares the single origin sandbox.e2b.app, and undici multiplexes up to 100 streams per H2 session, so a long-lived server effectively rides one session. One GOAWAY on it breaks file writes process-wide.
Issue reproduction
Hard to trigger from a fresh script (a new process has a fresh session with no accumulated history). Reliable in a long-lived Node server that:
Creates a pool of sandboxes and uploads a few MB to each with files.write
Lets them idle 1-3 minutes
On acquire, bursts ~15 parallel small files.write calls
After some process uptime, the edge in front of sandbox.e2b.app sends ENHANCE_YOUR_CALM (its rapid-reset / stream-abuse protection) and the failure mode above begins.
Additional context
Root cause is a combination of a server behavior and a client bug:
envd itself is an HTTP/1.1 Go server, so the H2 conversation is undici and your edge load balancer. The ENHANCE_YOUR_CALM GOAWAY comes from the edge.
Workaround we verified A/B: patching buildDispatchedFetch to allowH2: false (HTTP/1.1, the pre-2.19.5 transport) fully resolves it under identical load. There is currently no supported way to do this: no env var, no ConnectionConfig option, and no custom fetch injection, so we're shipping a pnpm patch.
Suggested fixes, any of which would let us drop the patch:
Sandbox ID or Build ID
ilsr5jnqvfbe9ez17h0b8 (one of many affected)
Environment
e2b (JS SDK) 2.38.0, Node 22.23.2 on Linux (Fly.io) and Node 23.6.0 on macOS 14.
loadUndiciselects theundici8optional dependency, which resolves to undici 8.8.0.Timestamp of the issue
First seen 2026-08-04 00:42 UTC; cause chains captured 2026-08-04 14:29 UTC.
Frequency
Happens every time
Expected behavior
When the server ends an HTTP/2 session (GOAWAY), the cost should be at most the in-flight requests. The SDK (or undici underneath it) should open a fresh connection for subsequent requests, and ideally retry streams the server refused, per RFC 9113 §8.7.
Actual behavior
Once one
files.writefails with:every subsequent
files.writein the process fails withNGHTTP2_INTERNAL_ERROR, including immediate retries, across all sandboxes, until the process restarts. Filesystem calls that go through the connect-RPC transport (files.makeDir) keep working on the same sandbox at the same moment, because that transport uses a separate dispatcher.This took our chat product down: since 2.25.0 all sandboxes' envd traffic shares the single origin
sandbox.e2b.app, and undici multiplexes up to 100 streams per H2 session, so a long-lived server effectively rides one session. One GOAWAY on it breaks file writes process-wide.Issue reproduction
Hard to trigger from a fresh script (a new process has a fresh session with no accumulated history). Reliable in a long-lived Node server that:
files.writefiles.writecallsAfter some process uptime, the edge in front of
sandbox.e2b.appsendsENHANCE_YOUR_CALM(its rapid-reset / stream-abuse protection) and the failure mode above begins.Additional context
Root cause is a combination of a server behavior and a client bug:
ENHANCE_YOUR_CALMGOAWAY comes from the edge.max_keepalive_connections#1418 and wait_for_build_finish crashes on transient HTTP/2 connection errors (ConnectionTerminated) #1488 show the same shape in httpx/h2.Workaround we verified A/B: patching
buildDispatchedFetchtoallowH2: false(HTTP/1.1, the pre-2.19.5 transport) fully resolves it under identical load. There is currently no supported way to do this: no env var, noConnectionConfigoption, and no custom fetch injection, so we're shipping a pnpm patch.Suggested fixes, any of which would let us drop the patch:
undici8dependency to >= 8.10.0ConnectionConfigoption) for HTTP/2