Skip to content

[v26.x] http2: do not reset stream before END_STREAM is sent - #66672

Open
barathraj048 wants to merge 1 commit into
nodejs:v26.x-stagingfrom
barathraj048:fix-http2-end-stream-rst
Open

barathraj048 wants to merge 1 commit into
nodejs:v26.x-stagingfrom
barathraj048:fix-http2-end-stream-rst

Conversation

@barathraj048

@barathraj048 barathraj048 commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

When a compat API response finishes and the request had no body,
kMaybeDestroy() takes the graceful-close path and sends RST_STREAM(NO_ERROR)
right away. If the connection flow-control window is exhausted at that
point, the empty END_STREAM DATA frame is still queued, so the reset goes
out first and END_STREAM is dropped. The client gets the full body but no
END_STREAM, so it treats the response as incomplete.

This skips the graceful close when the request already ended with its
HEADERS frame, since there is no request body to stop.

This targets v26.x-staging because main is not affected: the trailer
changes in #64265 avoid this path, but the v26 backport (#64663) left
them out. I could also reproduce it on v22.16.0, and the issue reports
v24.x too.

Testing:

  • Repro script from the issue: RST_STREAM(code=0) before the fix,
    DATA(0B, END_STREAM) after.
  • Added test-http2-compat-serverresponse-end-stream-flow-control.js. It
    checks that /small gets END_STREAM before any reset, and that the server
    stream still closes on its own.
  • python tools/test.py "parallel/test-http2-*": 283 passed (Windows x64).

Fixes: #66525
Refs: #64265
Refs: #64663

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/http2
  • @nodejs/net

@nodejs-github-bot nodejs-github-bot added http2 Issues and PRs related to the http2 subsystem. needs-ci PRs that need a full CI run. v26.x Issues that can be reproduced on v26.x or PRs targeting the v26.x-staging branch. labels Oct 12, 2026
When a compat API response finishes and the request had no body,
kMaybeDestroy() takes the graceful-close path and sends
RST_STREAM(NO_ERROR) right away. If the connection flow-control
window is exhausted at that point, the empty END_STREAM DATA frame
is still queued, so the reset goes out first and the END_STREAM
frame is dropped, truncating an otherwise complete response.

Skip the graceful close when the request already ended with its
HEADERS frame, since there is no request body to abort.

Fixes: nodejs#66525
Refs: nodejs#64265
Refs: nodejs#64663
Signed-off-by: Barath <barathraj048@gmail.com>
@barathraj048
barathraj048 force-pushed the fix-http2-end-stream-rst branch from 4279500 to ec8c98c Compare October 12, 2026 05:28
@codecov

codecov Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.74%. Comparing base (ca26282) to head (ec8c98c).
⚠️ Report is 1246 commits behind head on v26.x-staging.

Additional details and impacted files
@@                Coverage Diff                @@
##           v26.x-staging   #66672      +/-   ##
=================================================
+ Coverage          90.24%   90.74%   +0.49%     
=================================================
  Files                729      774      +45     
  Lines             242760   271784   +29024     
  Branches           46044    52069    +6025     
=================================================
+ Hits              219073   246619   +27546     
- Misses             15133    16065     +932     
- Partials            8554     9100     +546     
Files with missing lines Coverage Δ
lib/internal/http2/core.js 95.38% <100.00%> (-0.15%) ⬇️

... and 400 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@barathraj048 barathraj048 changed the title http2: do not reset stream before END_STREAM is sent http2: do not reset stream before END_STREAM is sent (v26.x) Oct 12, 2026
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@aduh95 aduh95 changed the title http2: do not reset stream before END_STREAM is sent (v26.x) [v26.x] http2: do not reset stream before END_STREAM is sent Oct 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

http2 Issues and PRs related to the http2 subsystem. needs-ci PRs that need a full CI run. v26.x Issues that can be reproduced on v26.x or PRs targeting the v26.x-staging branch.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants