Skip to content

fix(h2): send RST_STREAM(CANCEL) when aborting a stream with a queued body - #6191

Open
atty57 wants to merge 1 commit into
nodejs:mainfrom
atty57:fix/h2-abort-queued-body-rst-stream
Open

atty57 wants to merge 1 commit into
nodejs:mainfrom
atty57:fix/h2-abort-queued-body-rst-stream

Conversation

@atty57

@atty57 atty57 commented Nov 10, 2026

Copy link
Copy Markdown

Fixes #6187

Problem

The HTTP/2 abort handler in writeH2 called stream.close() (NO_ERROR) and then util.destroy(stream). While the request body is still queued behind flow control, Node defers the RST_STREAM until 'finish', which never comes; the destroy then drops the stream in Node while nghttp2 still holds it open with an active data provider. Once the server grants window, the session loops on empty DATA frames until the process is OOM-killed.

Fix

Give each writeH2 call its own AbortController, pass its signal to session.request(), and abort it in the abort handler instead of calling close(). Node then destroys the stream with an AbortError, submitting RST_STREAM(CANCEL) first. The synchronous destroy is kept as a fallback (#5558). The user's signal is no longer passed to Node — it already drives this abort handler via request.onRequestStart(), and the resulting AbortError 'error' on the stream is absorbed by the existing onError handler (the request is already marked aborted).

Alternatives from #6187 were not used: close(NGHTTP2_CANCEL) still runs away for streaming bodies, and destroy(stream, err) sends INTERNAL_ERROR instead of CANCEL.

Tests

New regression tests in test/http2-abort.js abort a request while its body (Buffer and streaming variants) is queued behind flow control against a server that never reads, and assert the server promptly receives RST_STREAM(CANCEL) and that the session stays usable. The other http2/h2 test files pass (a few files — h2-disconnect-guard, http2-connection, http2-dispatcher, http2-trailers — fail/hang identically on the unpatched baseline in my Windows environment).

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant