Skip to content

http2: fix onread assert when destroying session from stream handler - #65116

Open
sankalpsthakur wants to merge 3 commits into
nodejs:mainfrom
sankalpsthakur:fix/64850-http2-onread-assert
Open

http2: fix onread assert when destroying session from stream handler#65116
sankalpsthakur wants to merge 3 commits into
nodejs:mainfrom
sankalpsthakur:fix/64850-http2-onread-assert

Conversation

@sankalpsthakur

@sankalpsthakur sankalpsthakur commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

When session.destroy() runs from a stream handler, deferred session closure can allow later HEADERS in the same receive buffer to create C++ streams without a JavaScript wrapper. Subsequent DATA delivery can then hit the onread->IsFunction() assertion.

This change rejects new streams while the session is closing and destroys a C++ stream handle if its headers reach JavaScript after the session was destroyed.

The regression test is test/parallel/test-http2-session-destroy-stream-handler.js, which repeatedly destroys a session while handling concurrent POSTs.

Fixes #64850.

AI disclosure

AI coding tools, including Grok and Codex, assisted with the code and description.

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/http2
  • @nodejs/net

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. http2 Issues and PRs related to the http2 subsystem. needs-ci PRs that need a full CI run. labels Aug 7, 2026

@mcollina mcollina left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@mcollina mcollina added the request-ci Add this label to start a Jenkins CI on a PR. Only starts once the PR has an approving review. label Aug 31, 2026
@mcollina
mcollina requested a review from pimterry August 31, 2026 09:44
@github-actions github-actions Bot removed the request-ci Add this label to start a Jenkins CI on a PR. Only starts once the PR has an approving review. label Aug 31, 2026
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@codecov

codecov Bot commented Aug 31, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 66.66667% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 89.98%. Comparing base (2befec5) to head (eaa9b7a).
⚠️ Report is 202 commits behind head on main.

Files with missing lines Patch % Lines
lib/internal/http2/core.js 50.00% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #65116      +/-   ##
==========================================
- Coverage   89.99%   89.98%   -0.02%     
==========================================
  Files         757      757              
  Lines      257739   257750      +11     
  Branches    48881    48879       -2     
==========================================
- Hits       231961   231943      -18     
- Misses      16861    16899      +38     
+ Partials     8917     8908       -9     
Files with missing lines Coverage Δ
src/node_http2.cc 81.83% <100.00%> (-0.11%) ⬇️
lib/internal/http2/core.js 94.99% <50.00%> (-0.10%) ⬇️

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

@pimterry pimterry left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @sankalpsthakur!

Mostly looks good. The 3 fixes seem to all separately solve the same issue redundantly, is that right? I think for the first two that's OK and they're independently valuable (with minor tweaks) but we should drop the 3rd chunk to avoid missing major issues in future.

There's also a failing lint here, you can fix this locally with make format-cpp.

Comment thread src/node_http2.cc Outdated
Comment thread src/node_http2.cc Outdated
Comment thread lib/internal/http2/core.js
@mcollina

mcollina commented Sep 2, 2026

Copy link
Copy Markdown
Member

@pimterry ptal

@mcollina mcollina left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@mcollina mcollina added the request-ci Add this label to start a Jenkins CI on a PR. Only starts once the PR has an approving review. label Sep 2, 2026
@sankalpsthakur
sankalpsthakur force-pushed the fix/64850-http2-onread-assert branch from ae6f128 to 9cd30dd Compare September 2, 2026 17:23
When session.destroy() runs from a 'stream' handler, MakeCallback drains
nextTick while nghttp2 is still inside mem_recv. Close is deferred for
that window (see nodejs#64166), so later HEADERS in the same buffer created
C++ streams without a JS wrapper or onread, and DATA delivery aborted
with Assertion failed: onread->IsFunction().

- Reject new streams while the session is closing
- Destroy the C++ handle if on_headers runs after JS destroy
- Drop DATA when onread is not installed (defensive)

Fixes: nodejs#64850
Signed-off-by: Sankalp Thakur <sankalphimself@gmail.com>
@sankalpsthakur
sankalpsthakur force-pushed the fix/64850-http2-onread-assert branch from 9cd30dd to eaa9b7a Compare September 2, 2026 17:27

@pimterry pimterry left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for working through those fixes @sankalpsthakur!

@github-actions github-actions Bot removed the request-ci Add this label to start a Jenkins CI on a PR. Only starts once the PR has an approving review. label Sep 2, 2026
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@mcollina mcollina left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@sankalpsthakur

Copy link
Copy Markdown
Contributor Author

The child checks are green, but Jenkins #76961 still reports failure. The console requires authentication. Could someone share the failing stage or test?

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

Labels

c++ Issues and PRs that require attention from people who are familiar with C++. http2 Issues and PRs related to the http2 subsystem. needs-ci PRs that need a full CI run.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

http2: assertion failure onread->IsFunction() when a session is destroyed from a 'stream' handler

4 participants