Skip to content

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

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

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 <[email protected]>
@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?

mcollina pushed a commit that referenced this pull request Sep 14, 2026
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 #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: #64850
Signed-off-by: Sankalp Thakur <[email protected]>
PR-URL: #65116
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Tim Perry <[email protected]>
@mcollina

Copy link
Copy Markdown
Member

Landed in 0e32ee2

@mcollina mcollina closed this Sep 14, 2026
aduh95 pushed a commit that referenced this pull request Sep 16, 2026
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 #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: #64850
Signed-off-by: Sankalp Thakur <[email protected]>
PR-URL: #65116
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Tim Perry <[email protected]>
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