What happens
The Stress (Debug, linux, ubuntu-24.04, x64, openssl, -SanitizeAddress, -Test) job aborts on an assertion in QuicCryptoDiscardKeys:
#5 quic_bugcheck (File="src/core/crypto.c", Line=566,
Expr="Crypto->MaxSentLength >= BufferOffset")
#6 QuicCryptoDiscardKeys (Crypto=0x521000a38fe0, KeyType=QUIC_PACKET_KEY_INITIAL) crypto.c:566
#7 QuicPacketBuilderPrepare (NewPacketKeyType=QUIC_PACKET_KEY_HANDSHAKE) packet_builder.c:362
#8 QuicPacketBuilderPrepareForControlFrames (SendFlags=4) packet_builder.c:646
#9 QuicSendFlush send.c:1924
#10 QuicConnDrainOperations connection.c:10445
#11 QuicWorkerProcessConnection worker.c:660
Command: spinquic both -timeout:600000 -repeat_count:20 -alloc_fail:100
Seen on https://github.com/seera-networks/msquic/actions/runs/32583070808/job/97059321230 (PR #82). It is intermittent — the same job passes on other runs, and other Linux stress configurations in the same run passed.
Where it comes from
QuicPacketBuilderPrepare discarding the client's Initial keys is upstream #5899 (2026-04-20, "Fix client Initial key discard to trigger on any Handshake packet send"). git merge-base --is-ancestor confirms it predates every branch we currently carry, so this is inherited rather than ours.
The assertion itself is much older, from upstream microsoft#393.
Upstream has hit the same Crypto->MaxSentLength invariant under spinquic with -alloc_fail before — microsoft/msquic#6058 and #6059 — where it was analysed as a data race between the API caller's thread and the connection's worker, with -alloc_fail widening the window. Those were on a different stack (the connection pool path), so this may or may not be the same root cause.
Why this is filed rather than fixed
Nothing in this repository's own changes touches crypto.c, packet_builder.c or send.c. Fixing it means changing code we track from upstream, which we would rather not diverge on for a race we have not characterised.
Recorded so that:
- a reviewer seeing this red does not spend time re-deriving that it is not from the PR in front of them
- if it becomes frequent, we have the history to judge whether it is worth reporting upstream with our own repro
Not to be confused with
#84 — the Windows stress assert in binding.c, same run, different assertion.
What happens
The
Stress (Debug, linux, ubuntu-24.04, x64, openssl, -SanitizeAddress, -Test)job aborts on an assertion inQuicCryptoDiscardKeys:Command:
spinquic both -timeout:600000 -repeat_count:20 -alloc_fail:100Seen on https://github.com/seera-networks/msquic/actions/runs/32583070808/job/97059321230 (PR #82). It is intermittent — the same job passes on other runs, and other Linux stress configurations in the same run passed.
Where it comes from
QuicPacketBuilderPreparediscarding the client's Initial keys is upstream #5899 (2026-04-20, "Fix client Initial key discard to trigger on any Handshake packet send").git merge-base --is-ancestorconfirms it predates every branch we currently carry, so this is inherited rather than ours.The assertion itself is much older, from upstream microsoft#393.
Upstream has hit the same
Crypto->MaxSentLengthinvariant under spinquic with-alloc_failbefore — microsoft/msquic#6058 and #6059 — where it was analysed as a data race between the API caller's thread and the connection's worker, with-alloc_failwidening the window. Those were on a different stack (the connection pool path), so this may or may not be the same root cause.Why this is filed rather than fixed
Nothing in this repository's own changes touches
crypto.c,packet_builder.corsend.c. Fixing it means changing code we track from upstream, which we would rather not diverge on for a race we have not characterised.Recorded so that:
Not to be confused with
#84 — the Windows stress assert in
binding.c, same run, different assertion.