Skip to content

Kestrel HTTP/2 initial SETTINGS frame ignores defaults #63006

@deanward81

Description

@deanward81

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

We have a customer that is using the golang http module to make HTTP/2 requests to our service running Kestrel. By default we don't configure MaxConcurrentStreams in Http2Limits so we're using the default value (as per the spec) of 100 max concurrent streams.

In Http2PeerSettings.GetNonProtocolDefaults MaxConcurrentStreams is not passed to the SETTINGS frame if it is set to the default value. That should be fine, except Go's HTTP/2 client fallsback to a default value of 1000 streams if it doesn't receive a value in the server's SETTINGS frame!

It's probably worth mentioning that HTTP.SYS sends the value in the SETTINGS frame irrespective of whether it is a default value or not, so there is prior art there.

Expected Behavior

I'm not honestly sure if this should be viewed as a bug in Kestrel or a bug in golang's http/2 client implementation. It seems odd for the client to decide that 1000 streams is appropriate given the protocol default is 100. That said, this might not be the only client that behaves in this way so maybe this is something Kestrel could fix holistically by simply sending the default value in the SETTINGS frame.

Steps To Reproduce

  1. Leave Kestrel HTTP/2 MaxConcurrentStreams configured using the protocol-default value of 100 streams.
  2. Use a Go-based load testing tool like Bombardier to create a large number of connections to Kestrel.
  3. Observe that Bombardier attempts to use 1000 streams before making a new connection. 900 of these will be rejected.

Exceptions (if any)

No response

.NET Version

9.0.302

Anything else?

golang 1.24

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-networkingIncludes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractionsfeature-kestrel

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions