You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Fix h3 connection-level and stream-level abort locking #68101
When h3 is flooded with connection-level and stream-level aborts (which requires manually handling h3/QUIC streams, not regular HTTP requests), the codepaths can deadlock. The server keeps working fine. It's just wasting deadlocked threads.
We see this in production (ASP.NET Core 10.0.12, Native AOT, linux-arm64) and the impact is bigger than blocked threads: the connection-level abort loop holds _streams while it deadlocks, so the heartbeat thread blocks in Http3Connection.UpdateStreamTimeouts forever. No Kestrel timeout fires any more for any connection, the Date header freezes, and because the QUIC transport uses an infinite idle timeout, connections of vanished clients accumulate until the pod runs out of memory (about 600 per day here).
The trigger is plain HTTP: a client disappearing in the middle of a Brotli-compressed static-file download (HttpResponseStream.WriteAsync -> Http3OutputProducer.WriteDataToPipeAsync -> Http3Stream.AbortCore). Reproduction: 24 parallel downloads of a 545 KB file over one HTTP/3 connection from a NAT'ed Docker curl, SIGKILL the client after about one second; roughly one in four attempts freezes the heartbeat.
Could #69150 make the next 10.0 servicing release? 10.0.12 still has the old locking.
Activity
kekrops commentedon Oct 8, 2026
We see this in production (ASP.NET Core 10.0.12, Native AOT, linux-arm64) and the impact is bigger than blocked threads: the connection-level abort loop holds
_streamswhile it deadlocks, so the heartbeat thread blocks inHttp3Connection.UpdateStreamTimeoutsforever. No Kestrel timeout fires any more for any connection, theDateheader freezes, and because the QUIC transport uses an infinite idle timeout, connections of vanished clients accumulate until the pod runs out of memory (about 600 per day here).The trigger is plain HTTP: a client disappearing in the middle of a Brotli-compressed static-file download (
HttpResponseStream.WriteAsync -> Http3OutputProducer.WriteDataToPipeAsync -> Http3Stream.AbortCore). Reproduction: 24 parallel downloads of a 545 KB file over one HTTP/3 connection from a NAT'ed Docker curl, SIGKILL the client after about one second; roughly one in four attempts freezes the heartbeat.Could #69150 make the next 10.0 servicing release? 10.0.12 still has the old locking.