Skip to content

moq-lite-06: an oversize GOAWAY URI and a Message Length mismatch end only the stream; the session is never closed #5259

Closed

Description

@mondain

Problem

A decode error on a control stream (Announce, Subscribe, Goaway, ...) is logged and ends only that stream; the session is never closed. Two draft rules need a session close:

  1. GOAWAY URI over 8,192 bytes (MUST). Draft section 7.18: "The URI MUST NOT exceed 8,192 bytes; a receiver MUST treat a longer URI as a protocol violation and MAY reject it based on the length prefix alone." The same section closes the session with PROTOCOL_VIOLATION for the other GOAWAY violations.
  2. Message Length that disagrees with the content (SHOULD). Draft section 7.1: "An implementation SHOULD close the connection with a PROTOCOL_VIOLATION if it receives a message with an unexpected length."

Repro

Against moq as publisher over moq-lite-06, native QUIC or WebTransport:

  1. Oversize GOAWAY: open a Goaway Stream (bidirectional, type 0x5) with a message claiming an 8193-byte URI: 05 60 03 60 01 61 61 ... (then 8193 bytes). The CLI resets the Goaway Stream with CANCELLED (0x1) about 2 ms later and sends STOP_SENDING 0. The session stays open for the whole 3 s I waited.
  2. Length mismatch: open an Announce Stream with 01 04 00 6c 31 64 (stream type 0x1, Message Length 4, but the message is an empty Broadcast Path Prefix plus three trailing bytes). The CLI logs WARN moq_net::lite::message: decode failed err=long buffer and WARN moq_net::lite::publisher: control stream error err=long buffer, resets the stream with CANCELLED and sends STOP_SENDING 0. The session stays open.

Verified on moq 0.14.2 from main at 954505e (both cases reproduce) and on 0.14.1 at b8b0d23.

Where

  • rs/moq-net/src/lite/goaway.rs decode_msg rejects a length above 8192 from the prefix alone (DecodeError::InvalidValue), as the draft allows.
  • rs/moq-net/src/lite/message.rs reports trailing bytes as DecodeError::Long.
  • rs/moq-net/src/lite/publisher.rs then treats both as a per-stream error: the comment "A decode error propagates to the caller, which logs and continues" explains that a malformed GOAWAY must not tear down the session it is trying to drain, and the control loop only logs per-stream errors.

Suggested fix

Map these two decode errors to a session close with PROTOCOL_VIOLATION on the control streams. A draining session can still be closed by a protocol violation; the draft does not exempt it. If the continue-on-error design is deliberate for other decode errors, the oversize GOAWAY URI (a MUST) still needs the close.


Found with an interop runner (mondain/moq-contribution-interop-runner, docs/moq-lite-punch-list.md items ML-05 and ML-03; rows L06-7-18-MUST-179 and L06-7-1-SHOULD-107). Drafted with AI assistance; the bytes and logs above are from real runs.

Activity

  1. added
    questBeing tracked/planned in a quest. See `quest/`
    on Oct 12, 2026
  2. kixelated commented on Oct 12, 2026

    @kixelated
    Collaborator

    Confirmed in Rust, and in js/net too where it applies. We're fixing #5257, #5258 and #5259 together in one quest, quest/m1/lite-malformed-close.md, planned in #5358. Decisions:

    • SETUP: a client closes with PROTOCOL_VIOLATION on Path or Role in the server's SETUP. A server also closes on Path over a binding whose handshake carries a URI.
    • PROBE: a Report-level publisher decodes PROBE targets and keeps reporting. Only a FIN or a reset ends the stream.
    • Control streams: any decode error on a control stream closes the session with PROTOCOL_VIOLATION, not just the two cases cited. This includes child handlers and response decoders on streams we opened. Data-stream decode errors stay per-stream.

    The rules are the same from lite-06 through lite-07-wip, so the fix covers every lite version. Thanks for the precise byte-level repros.

    Anyone who wants to donate tokens can run /quest-start quest/m1/lite-malformed-close.

    (Written by Claude Opus 5.5)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    questBeing tracked/planned in a quest. See `quest/`

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions