Skip to content

x/net/http2: server unconditionally sends SETTINGS_NO_RFC7540_PRIORITIES=1 by default since v0.50.0, incompatible with connection multiplexers #77947

@lukeo3o1

Description

@lukeo3o1

Go version

go1.26.0 windows/amd64

Output of go env in your module/workspace:

N/A

What did you do?

Used golang.org/x/net@v0.50.0 (or later) with an HTTP/2 server behind a connection multiplexer such as cmux, which sniffs the connection preface and optionally sends a bare SETTINGS frame before handing the net.Conn off to http2.Server.ServeConn.

What did you see happen?

Clients (Chrome, Edge, etc.) close the connection immediately with:

GOAWAY ErrCode=PROTOCOL_ERROR
Debug="spdy::SETTINGS_DEPRECATE_HTTP2_PRIORITIES value changed after first SETTINGS frame."

What did you expect to see?

http2.Server should not emit SETTINGS_NO_RFC7540_PRIORITIES=1 by default. Prior to v0.50.0, this setting was never sent, and the behavior change should require an explicit opt-in rather than being a side-effect of the default write schedulers (*randomWriteScheduler, *roundRobinWriteScheduler).


Root Cause

Two related changes landed in golang.org/x/net@v0.50.0 as part of #75500:

  1. A new helper method writeSchedIgnoresRFC7540() was introduced. Notably, both *randomWriteScheduler and *roundRobinWriteScheduler — the two default schedulers most users run — return true:
    https://github.com/golang/net/blob/ebddb99633e0fc35d135f62e9400678492c1d3be/http2/server.go#L660-L671
  2. When writeSchedIgnoresRFC7540() returns true, the server now unconditionally appends SettingNoRFC7540Priorities = 1 to its initial SETTINGS frame:
    https://github.com/golang/net/blob/ebddb99633e0fc35d135f62e9400678492c1d3be/http2/server.go#L961-L963

Failure Sequence

  1. cmux reads the HTTP/2 client connection preface and sends a bare SETTINGS frame to the client (no SETTINGS_DEPRECATE_HTTP2_PRIORITIES, so value is implicitly 0).
  2. The connection is handed off to http2.Server.ServeConn.
  3. http2.Server sends its own SETTINGS frame, now including SETTINGS_DEPRECATE_HTTP2_PRIORITIES = 1.
  4. The client observes this value changing from 0 to 1 across two SETTINGS frames. RFC 9218 §9.1 prohibits this: a sender MUST NOT revert this setting once enabled.
  5. Client closes with GOAWAY / PROTOCOL_ERROR.

Discussion: Why DisableClientPriority Does Not Fix On-wire Regression

DisableClientPriority (planned for Go 1.27, see #75500) is designed to control the server's stream scheduling behavior. It disables client-driven prioritization and selects round-robin across all streams. However, this does not prevent the server from setting SettingNoRFC7540Priorities=1 in its initial SETTINGS frame, as roundRobinWriteScheduler still returns true for writeSchedIgnoresRFC7540().

Therefore, the on-wire protocol regression described above remains unaddressed. There is no current mechanism for applications using cmux-style intermediaries to suppress emission of SETTINGS_NO_RFC7540_PRIORITIES from Go's HTTP/2 server.


Possible Directions

  1. Restrict writeSchedIgnoresRFC7540() to opt-in schedulers only — Only explicit adoption of the RFC 9218 priority scheduler would emit SETTINGS_NO_RFC7540_PRIORITIES=1. The default scheduling (including round-robin and random) should preserve pre-v0.50.0 on-wire behavior.

  2. Add an explicit flag to control emission of SETTINGS_NO_RFC7540_PRIORITIES — e.g., a NoRFC7540Priorities bool field on http2.Server. This would decouple scheduling logic from frame signaling.

Either option would allow advanced use cases (like cmux) to avoid breaking HTTP/2 interoperability with some clients.

Happy to hear thoughts from the maintainers on which direction or solution is preferred.

Related: #75500

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugReportIssues describing a possible bug in the Go implementation.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions