GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — stream: fix flaky stream destroy, reachable from HTTP/2 teardown by pimterry · Pull Request #65079 · nodejs/node

Conversation

@pimterry

@pimterry pimterry commented Aug 6, 2026

Copy link
Copy Markdown
Member

Some of the HTTP/2 tests have become flaky, e.g. nodejs/reliability#1623 shows yesterday:

  • parallel/test-worker-terminate-http2-respond-with-file failed 11 times
  • parallel/test-stream-pipeline-http2 failed 10 times

Best guess is these are both due to the window update PR #64623 (cc @mcollina) since the timing lines up exactly. I think this is really just the window size highlighting existing issues though.

This PR fixes the first issue, which triggers flakes in parallel/test-worker-terminate-http2-respond-with-file. I'll kick off a stress test to confirm, but I can reproduce this locally, and reproduced as resolved with this fix. I'm still working on the 2nd, which only reproduces on Mac and seems a bit more complex.

Actual failure in the 1st test is a crash with pure virtual method called. That fires due to ReadStop within this trace:

Worker::Run → FreeEnvironment
  → Environment::RunCleanup
    → BaseObjectList::Cleanup
      → fs::FileHandle::~FileHandle
        → StreamResource::~StreamResource
          → StreamPipe::ReadableListener::OnStreamDestroy
            → StreamPipe::ReadableListener::OnStreamRead

I.e. during destroy within the destructor chain, we call OnStreamRead, which tries to call stream()->ReadStop inside the sources destructor.

This is only called because OnStreamDestroy manually calls OnStreamRead with an error code to reuse its error/eof teardown logic. We don't need most of that in the destruction scenario (which is only ever called from ~StreamResource, where the stream is already dead).

I've refactored out the relevant bit to split them up (just guarding just fails in the next line, where previous_listener_ is also null). That then exposed two other bugs for the same state, where two other methods that get reached later in this teardown flow also fail to check if the stream is already destroyed - those just need simple guards.

Seems like this is a flaky race because it depends on whether the sink (Http2Stream) or the file handle gets destroyed first by Cleanup().

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@pimterry
stream: fix flaky stream destroy, reachable from HTTP/2 teardown
2f4238d
Signed-off-by: Tim Perry <[email protected]>
@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. needs-ci PRs that need a full CI run. labels Aug 6, 2026
@pimterry

pimterry commented Aug 6, 2026

Copy link
Copy Markdown
Member Author

cc @nodejs/http2

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@codecov

codecov Bot commented Aug 6, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.32%. Comparing base (b33cc0e) to head (da4b684).
⚠️ Report is 81 commits behind head on main.

Files with missing lines Patch % Lines
src/stream_pipe.cc 0.00% 5 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #65079      +/-   ##
==========================================
+ Coverage   90.29%   90.32%   +0.03%     
==========================================
  Files         759      759              
  Lines      247598   248458     +860     
  Branches    46680    46869     +189     
==========================================
+ Hits       223566   224420     +854     
+ Misses      15503    15448      -55     
- Partials     8529     8590      +61     
Files with missing lines Coverage Δ
src/stream_pipe.cc 58.71% <0.00%> (-1.47%) ⬇️

... and 87 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.
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

anonrig
anonrig approved these changes Aug 6, 2026
View reviewed changes
@pimterry

pimterry commented Aug 7, 2026

Copy link
Copy Markdown
Member Author

I'll kick off a stress test to confirm

Stress testing inconclusive - the tests passed on both main and this branch, even with multiple runs. They're definitely failing in PRs though. I can reliably reproduce the reported failure locally (that first failure above, it hits for 2-3% of runs) and validate that it's fixed with this change. The trace is where is crashes on my machine with the matching error, and it's clearly a broken flow, so I think this is the right fix regardless.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

mcollina
mcollina approved these changes Aug 7, 2026
View reviewed changes

@mcollina mcollina left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

lgtm

I concur with the analysis

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@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 7, 2026
@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 7, 2026
panva
panva approved these changes Aug 7, 2026
View reviewed changes
@panva panva added the author ready PRs with CI started, the required approvals, and no outstanding review comments. label Aug 7, 2026
@nodejs-github-bot

nodejs-github-bot commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

CI: https://ci.nodejs.org/job/node-test-pull-request/75628/

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@panva

panva commented Aug 7, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

Even with this PR's change I can still fail test-stream-pipeline-http2.js with a timeout 31/1000 times. Without it about 56/1000 times.

This diff that claude spit out to deflake test-stream-pipeline-http2.js makes that 0/1000 with or without this PR, but I don't know enough about this subsystem to say whether that retains the point of the test or not.

diff --git a/test/parallel/test-stream-pipeline-http2.js b/test/parallel/test-stream-pipeline-http2.js
--- a/test/parallel/test-stream-pipeline-http2.js
+++ b/test/parallel/test-stream-pipeline-http2.js
@@ -27,10 +27,11 @@
-    let cnt = 10;
+    let received = 0;
     req.on('data', (data) => {
-      cnt--;
-      if (cnt === 0) rs.destroy();
+      received += data.length;
+      // HTTP/2 data event boundaries are non-deterministic.
+      if (received >= 32 * 1024) rs.destroy();
     });
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@pimterry

pimterry commented Aug 7, 2026

Copy link
Copy Markdown
Member Author

Even with this PR's change I can still fail test-stream-pipeline-http2.js

Yes, sorry if the description isn't clear - both failing tests are related to that PR, but this PR only fixes the first of the two. I.e. test-worker-terminate-http2-respond-with-file.

I haven't opened a fix for the second yet, because I think it's actually exposed a real bug that's a bit complicated, and mac-only. Looks like that fix would resolve the test, but from what I can tell so far there's a real underlying deadlock that's reproducible independently, so I want to get a proper fix for that instead. I'll update when I have more info there.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@panva

panva commented Aug 9, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

@pimterry can you land this with the fix/workaround i posted to the remaining flake knowing you'll revisit the underlying deadlock problem and possibly change it again?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@pimterry @panva
test: avoid deadlock issue in pipeline http2 tests to fix flakiness
da4b684
This does not solve the remaining underlying deadlock issue, but does
bound the test behaviour in a way that seems to avoid failures in
practice. Deadlock fix to come separately later.

Co-authored-by: Filip Skokan <[email protected]>
Signed-off-by: Tim Perry <[email protected]>
panva
panva approved these changes Aug 9, 2026
View reviewed changes
@pimterry

pimterry commented Aug 9, 2026

Copy link
Copy Markdown
Member Author

Good plan @panva, now done 👍.

I'll open the other fix separately. I've got it working now but the deadlock comes from code we added to resolve past CVEs, so needs some thought and it'd be nice not to rush it.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@pimterry pimterry added request-ci Add this label to start a Jenkins CI on a PR. Only starts once the PR has an approving review. commit-queue-rebase PRs the Commit Queue should land as multiple self-contained commits. labels Aug 9, 2026
@panva panva removed the commit-queue-rebase PRs the Commit Queue should land as multiple self-contained commits. label Aug 9, 2026
@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 9, 2026
@nodejs-github-bot

This comment was marked as outdated.

Sign in to view
@panva panva added the commit-queue-rebase PRs the Commit Queue should land as multiple self-contained commits. label Aug 9, 2026
mcollina
mcollina approved these changes Aug 9, 2026
View reviewed changes

@mcollina mcollina left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

lgtm

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@nodejs-github-bot

nodejs-github-bot commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

CI: https://ci.nodejs.org/job/node-test-pull-request/75719/

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@pimterry pimterry added the commit-queue PRs queued for automated landing through the Commit Queue. label Aug 10, 2026
panva pushed a commit that referenced this pull request Aug 10, 2026
@pimterry @panva
stream: fix flaky stream destroy, reachable from HTTP/2 teardown
64a762b
Signed-off-by: Tim Perry <[email protected]>
PR-URL: #65079
Reviewed-By: Yagiz Nizipli <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Filip Skokan <[email protected]>
panva added a commit that referenced this pull request Aug 10, 2026
@pimterry @panva
test: avoid deadlock issue in pipeline http2 tests to fix flakiness
404b0cf
This does not solve the remaining underlying deadlock issue, but does
bound the test behaviour in a way that seems to avoid failures in
practice. Deadlock fix to come separately later.

Co-authored-by: Filip Skokan <[email protected]>
Signed-off-by: Tim Perry <[email protected]>
PR-URL: #65079
Reviewed-By: Yagiz Nizipli <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Filip Skokan <[email protected]>
@panva

panva commented Aug 10, 2026

Copy link
Copy Markdown
Member

Landed in 780229b...404b0cf

trivikr reacted with thumbs up emoji pimterry reacted with heart emoji
All reactions
  • 👍 1 reaction
  • ❤️ 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@panva panva closed this Aug 10, 2026
@panva panva removed the commit-queue PRs queued for automated landing through the Commit Queue. label Aug 10, 2026
aduh95 pushed a commit that referenced this pull request Aug 13, 2026
@pimterry @aduh95
stream: fix flaky stream destroy, reachable from HTTP/2 teardown
1e4c712
Signed-off-by: Tim Perry <[email protected]>
PR-URL: #65079
Reviewed-By: Yagiz Nizipli <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Filip Skokan <[email protected]>
aduh95 pushed a commit that referenced this pull request Aug 13, 2026
@pimterry @panva @aduh95
test: avoid deadlock issue in pipeline http2 tests to fix flakiness
b12c550
This does not solve the remaining underlying deadlock issue, but does
bound the test behaviour in a way that seems to avoid failures in
practice. Deadlock fix to come separately later.

Co-authored-by: Filip Skokan <[email protected]>
Signed-off-by: Tim Perry <[email protected]>
PR-URL: #65079
Reviewed-By: Yagiz Nizipli <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Filip Skokan <[email protected]>
@pimterry pimterry mentioned this pull request Aug 20, 2026
http2: fix write deadlock exposed by larger window sizes #65440
Merged
aduh95 pushed a commit that referenced this pull request Aug 25, 2026
@pimterry @panva @aduh95
test: avoid deadlock issue in pipeline http2 tests to fix flakiness
59d7e22
This does not solve the remaining underlying deadlock issue, but does
bound the test behaviour in a way that seems to avoid failures in
practice. Deadlock fix to come separately later.

Co-authored-by: Filip Skokan <[email protected]>
Signed-off-by: Tim Perry <[email protected]>
PR-URL: #65079
Reviewed-By: Yagiz Nizipli <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Filip Skokan <[email protected]>
@github-actions github-actions Bot mentioned this pull request Aug 25, 2026
2026-08-26, Version 26.8.0 (Current) #65551
Merged
aduh95 pushed a commit that referenced this pull request Aug 27, 2026
@pimterry @panva @aduh95
test: avoid deadlock issue in pipeline http2 tests to fix flakiness
881f8d0
This does not solve the remaining underlying deadlock issue, but does
bound the test behaviour in a way that seems to avoid failures in
practice. Deadlock fix to come separately later.

Co-authored-by: Filip Skokan <[email protected]>
Signed-off-by: Tim Perry <[email protected]>
PR-URL: #65079
Reviewed-By: Yagiz Nizipli <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Filip Skokan <[email protected]>
@aduh95

aduh95 commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

IIUC 64a762b should not be backported as it is based on a semver-major change. If I'm wrong, please open a manual backport PR

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@aduh95 aduh95 added the backported-to-v26.x PRs backported to the v26.x-staging branch. label Aug 27, 2026
@pimterry

pimterry commented Aug 27, 2026

Copy link
Copy Markdown
Member Author

@aduh95 this can actually be safely backported I think. It fixes a bug (broken stream teardown) that exists independently of the semver-major change (increasing default HTTP/2 window sizes) and shouldn't conflict with anything else I'm aware of.

The bug was effectively invisible with small HTTP/2 windows, but it's still technically present, and users could always manually configure window sizes in the past which would likely trigger this as well, so it's probably reachable in all versions.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@github-actions github-actions Bot mentioned this pull request Sep 7, 2026
2026-09-08, Version 24.21.0 'Krypton' (LTS) #65873
Merged
@aduh95 aduh95 mentioned this pull request Oct 27, 2026
2026-10-28, Version 27.0.0-alpha.0.0.0 (Alpha) #67062
Merged
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@mcollina mcollina mcollina approved these changes
@panva panva panva approved these changes
@anonrig anonrig anonrig approved these changes

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

author ready PRs with CI started, the required approvals, and no outstanding review comments. backported-to-v26.x PRs backported to the v26.x-staging branch. c++ Issues and PRs that require attention from people who are familiar with C++. commit-queue-rebase PRs the Commit Queue should land as multiple self-contained commits. needs-ci PRs that need a full CI run.

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

6 participants

@pimterry @nodejs-github-bot @panva @aduh95 @mcollina @anonrig
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.