Skip to content

Conversation

DeagleGross
Copy link
Member

Backport of #63873 to release/8.0

(http2): Lower WINDOWS_UPDATE received on (half)closed stream to stream abortion

Change affects the server HTTP/2 behavior in the case client sends the RST_STREAM frame (moving stream to half-closed or closed state) and then sends another packet - WINDOW_UPDATE. Server behavior varies in this case (RFC HTTP/2 does not describe this case extremely clear) - for example HTTP.SYS does interpet this as a stream-level error (ignore of WINDOW_UPDATE packet); but Kestrel is more strict and sends the GO_AWAY packet closing not only the stream, but also the whole connection.

Such restrictive behavior of Kestrel impacts the client, which observes cancellations and has to re-establish the connection frequently.

Fixes #63726

Customer Impact

1P Customer which processes intensive traffic of another 1P customer with a Golang-based client observes high volume of cancellations. This not only impacts the performance where a new connection has to be established, but also means all streams existing on the connection were lost, resulting in bunch of customers seeing high latency.

Regression?

  • Yes
  • No

Risk

  • High
  • Medium
  • Low

Small change in behavior making Kestrel less restrictive. Also is being tested by the 1P team.

Verification

  • Manual (required)
  • Automated

Packaging changes reviewed?

  • Yes
  • No
  • N/A

When servicing release/2.3

  • Make necessary changes in eng/PatchConfig.props

@Copilot Copilot AI review requested due to automatic review settings October 2, 2025 13:03
@dotnet-policy-service dotnet-policy-service bot added this to the 8.0.x milestone Oct 2, 2025
@DeagleGross DeagleGross self-assigned this Oct 2, 2025
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Adjusts Kestrel's HTTP/2 handling so that a WINDOW_UPDATE received after a client-initiated RST_STREAM results in a stream-level error instead of a connection-level GOAWAY, reducing unnecessary connection teardown and improving client resilience.

  • Change exception from connection-level (Http2ConnectionErrorException) to stream-level (Http2StreamErrorException).
  • Update accompanying test to assert a stream error and perform a graceful connection stop afterward.

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs Alters handling of WINDOW_UPDATE after RST_STREAM to throw stream-level exception; adds explanatory comment.
src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2ConnectionTests.cs Updates test to expect stream error and adjusts ordering to delay response start until after abort.

// stream in the "closed" state due to a reset by client. We surface it as a stream error (STREAM_CLOSED)
// rather than aborting the entire connection to keep behavior deterministic and consistent with other servers.
// https://github.com/dotnet/aspnetcore/issues/63726
throw new Http2StreamErrorException(_incomingFrame.StreamId, CoreStrings.Http2StreamAborted, Http2ErrorCode.STREAM_CLOSED);
Copy link

Copilot AI Oct 2, 2025

Choose a reason for hiding this comment

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

_incomingFrame.StreamId should always match stream.StreamId at this point, but using stream.StreamId would make the invariant explicit and reduce the chance of discrepancies if future changes adjust frame routing logic. Suggest replacing _incomingFrame.StreamId with stream.StreamId for clarity.

Copilot uses AI. Check for mistakes.

@wtgodbe wtgodbe added the Servicing-approved Shiproom has approved the issue label Oct 6, 2025
@wtgodbe
Copy link
Member

wtgodbe commented Oct 7, 2025

Test failure unrelated

@wtgodbe wtgodbe merged commit 2dd0c92 into release/8.0 Oct 7, 2025
23 of 25 checks passed
@wtgodbe wtgodbe deleted the dmkorolev/release8.0/http2-windowupdate branch October 7, 2025 20:17
@dotnet-policy-service dotnet-policy-service bot modified the milestones: 8.0.x, 8.0.22 Oct 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Servicing-approved Shiproom has approved the issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants