quic: crash when incoming unidirectional stream has no onstream handlerΒ #64030
Copy link
Copy link
Closed
Labels
quicIssues and PRs related to the QUIC transport implementation.Issues and PRs related to the QUIC transport implementation.
Description
When a QUIC server accepts a session without .onstream, and the client connects with a unidirectional stream with a body, Node crashes with SIGSEGV
If I use a bidirectional stream instead, it works. If I create the unidirectional stream without a body, it also does not crash.
Expected behaviour would be to safely destroy or at least not crash.
Repro:
import {readFileSync} from 'node:fs';
import {createPrivateKey} from 'node:crypto';
import {listen, connect} from 'node:quic';
const key = createPrivateKey(readFileSync(new URL('./key.pem', import.meta.url)));
const cert = readFileSync(new URL('./cert.pem', import.meta.url));
const serverEndpoint = await listen(async (session) => {
await session.opened;
console.log('Server session opened');
// Intentionally do not install .onstream
}, {
sni: {'*': {keys: [key], certs: [cert]}},
alpn: ['repro'],
});
const clientSession = await connect(serverEndpoint.address, {
servername: 'localhost',
alpn: 'repro',
ca: cert,
});
await clientSession.opened;
console.log('Client session opened');
await clientSession.createUnidirectionalStream({
body: 'something something darkside'
});
console.log('Unidirectional stream created');Outputs
(node:99156) ExperimentalWarning: quic is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
Client session opened
Unidirectional stream created
Server session opened
(node:99156) Warning: A new stream was received but no onstream callback was provided
(node:99156) Warning: A new stream was received but no onstream callback was provided
(node:99156) Warning: A new stream was received but no onstream callback was provided
fish: Job 1, './out/Release/node --experimentβ¦' terminated by signal SIGSEGV (Address boundary error)
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
quicIssues and PRs related to the QUIC transport implementation.Issues and PRs related to the QUIC transport implementation.
Activity
martenrichter commentedon Jun 21, 2026
I turned it into a test:
and tried to reproduce it on windows, but no luck. So I expect that it is a race condition or uninitialized memory, which may be system depent. However, my local main is still on martenrichter@a17d2b8 from yesterday, so may be it is a very recent commit. I try to update and test again.
martenrichter commentedon Jun 21, 2026
Does not crash either... on current main.
martenrichter commentedon Jun 21, 2026
My best bet is that something in
Stream::Destroy:node/src/quic/streams.cc
Line 1641 in 665daeb
crashes, where something is not protected against a unidirectional stream that has no write side.
So as you can reproduce it locally, add some printf in this function to narrow down the crash. As it does not crash on my install I can not help with the debugging part.
efekrskl commentedon Jun 26, 2026
Thanks for the input!
I've been debugging this over the last few days, as far as I see this is caused by JS synchronously destroying the stream and native code trying to access it. Weird you couldn't reproduce it though, it is 100% reproducable for me.
martenrichter commentedon Jun 27, 2026
So that means something on the native side is not holding a reference to JS long enough.
(You may want to look at my old PR #60237, the code basis change a bit since then, what I had fixed there many bugs like this, so if one of the fix is close to the parts you are debugging, it may be a match).
And where are the crashes happening?
And it is not so weird, that I can not repoduce it. These type of race condition triggered crashes depend on the timing, and also the timing of network packets. And Windows uses a different compiler, so memory is differently initialized. So it is often machine and OS dependent.
[Edit: I see you already made a PR, was not clear to me when writing the above]
efekrskl commentedon Jun 30, 2026
Yeah, I have a PR open, but I appreciate the input. I'm trying to get familiar with QUIC and it's implementation in Node.js, so any extra guidance helps :)
efekrskl commentedon Jul 11, 2026
Fixed #64158