WebTransport Echo

Exhibit · quic-go and webtransport-go

Three findings against the Go stack

All three are reproducible against this host. Each is separable from the others and from anything Apple does.


1. The zero-config default cannot serve Safari

Under a nil Config, addSettings deletes all three WT_INITIAL_MAX_* settings that v0.11.0 sent unconditionally, while ConfigureHTTP3Server forces WT_MAX_SESSIONS = 2^62−1.

draft-13 makes those three conditionally required whenever WT_MAX_SESSIONS exceeds 1. Safari 26.4 onward enforces it, so the out-of-the-box server is refused by current Safari with no diagnostic on either side.

Ask: restore the trio under a nil Config, or default WT_MAX_SESSIONS to 1. Separately, expose a seam for it. WT_MAX_SESSIONS is currently set inside init() inside Serve(), so only a fork can change it.

This one stands on API grounds regardless of what Apple concludes about the finding below.


2. A behavior change between v0.11/v0.60 and v0.12/v0.61

The newer pair is refused by Safari on iOS 27.0 beta where the older pair is accepted, while the SETTINGS and QUIC transport parameters the two advertise match on every value compared so far. If that comparison is complete, the difference is in behavior neither peer advertises: frame encoding, capsule handling, or sequencing. It has not been identified, and the comparison may be looking at the wrong things.

Server-side signature on the refusal: the peer opens the extended CONNECT stream, writes zero bytes, sends stop_sending(stream 0, 0x10C) and closes with 0x100. Full capture on the WebKit exhibit.

What this comparison cannot tell you. Two dependencies move between the two builds, so it does not isolate either one. Pinning webtransport-go v0.11.0 against quic-go v0.61.0 as a fifth endpoint would separate them: if that binds, the change is in webtransport-go v0.12; if it is refused, it is in quic-go v0.61; if the pairing will not compile, the two builds above are what a bisect has to start from. That endpoint does not exist yet.

Observed only on a beta OS, and only by this project. Apple may resolve it before GM, in which case this is a note rather than a report.


3. The Go client refuses peers that do not negotiate RESET_STREAM_AT

webtransport-go's client, v0.11 and v0.12 alike, hard-requires EnableStreamResetPartialDelivery and fails with "server didn't enable QUIC stream reset partial delivery" against any server that does not negotiate it.

No browser requires this. RESET_STREAM_AT is an extension, and a hard requirement on a non-negotiated extension makes the Go client unable to talk to conformant WebTransport servers, including wtransport, which this host runs on :4438.

# reproduces with either client version
go run ./client -url https://echo.semantic-ui.com:4438/echo

# server didn't enable QUIC stream reset partial delivery

Ask: treat RESET_STREAM_AT as optional, or negotiate it rather than requiring it.

Related: the WebKit side · what this means if you are building on WebTransport