Media Over QUIC A. Frindell Internet-Draft Meta Intended status: Standards Track 2 March 2026 Expires: 3 September 2026 QPACK Compression for MoQ Transport draft-frindell-moq-moqpack-00 Abstract This document defines an extension to Media over QUIC Transport (MOQT) that enables QPACK compression for control messages. By leveraging QPACK's dynamic table, this extension significantly reduces the overhead of repeated values such as track names and authorization tokens, improving efficiency for sessions with many subscriptions or frequent redundant values. About This Document This note is to be removed before publishing as an RFC. The latest revision of this draft can be found at https://afrind.github.io/draft-frindell-moq-moqpack/draft-frindell- moq-moqpack.html. Status information for this document may be found at https://datatracker.ietf.org/doc/draft-frindell-moq-moqpack/. Discussion of this document takes place on the Media Over QUIC Working Group mailing list (mailto:moq@ietf.org), which is archived at https://mailarchive.ietf.org/arch/browse/moq/. Subscribe at https://www.ietf.org/mailman/listinfo/moq/. Source for this draft and an issue tracker can be found at https://github.com/afrind/draft-frindell-moq-moqpack. Status of This Memo This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79. Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet- Drafts is at https://datatracker.ietf.org/drafts/current/. Frindell Expires 3 September 2026 [Page 1] Internet-Draft moq-moqpack March 2026 Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress." This Internet-Draft will expire on 3 September 2026. Copyright Notice Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved. This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/ license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License. Table of Contents 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 4 1.1. Motivation . . . . . . . . . . . . . . . . . . . . . . . 4 2. Conventions and Definitions . . . . . . . . . . . . . . . . . 4 3. Extension Negotiation . . . . . . . . . . . . . . . . . . . . 5 3.1. MOQT_QPACK_MAX_TABLE_CAPACITY . . . . . . . . . . . . . . 5 3.2. MOQT_QPACK_BLOCKED_STREAMS . . . . . . . . . . . . . . . 5 3.3. MOQT_QPACK_INDEX_SETUP_AUTH . . . . . . . . . . . . . . . 5 4. QPACK Streams . . . . . . . . . . . . . . . . . . . . . . . . 6 4.1. Stream Types . . . . . . . . . . . . . . . . . . . . . . 6 4.2. Stream Initialization . . . . . . . . . . . . . . . . . . 7 4.3. Stream Lifetime . . . . . . . . . . . . . . . . . . . . . 7 5. Compressed Message Formats . . . . . . . . . . . . . . . . . 7 5.1. MOQPACK Flag Bit . . . . . . . . . . . . . . . . . . . . 7 5.2. Pseudo-Parameter Types . . . . . . . . . . . . . . . . . 8 5.2.1. TRACK_NAMESPACE_SET Value Format . . . . . . . . . . 8 5.3. Namespace Reconstruction . . . . . . . . . . . . . . . . 9 5.4. Field Ordering . . . . . . . . . . . . . . . . . . . . . 10 5.5. Required Fields . . . . . . . . . . . . . . . . . . . . . 10 5.6. MOQPACK Message Formats . . . . . . . . . . . . . . . . . 10 5.6.1. SUBSCRIBE . . . . . . . . . . . . . . . . . . . . . . 10 5.6.2. PUBLISH . . . . . . . . . . . . . . . . . . . . . . . 11 5.6.3. FETCH . . . . . . . . . . . . . . . . . . . . . . . . 11 5.6.4. SUBSCRIBE_NAMESPACE . . . . . . . . . . . . . . . . . 12 5.6.5. PUBLISH_NAMESPACE . . . . . . . . . . . . . . . . . . 12 5.6.6. NAMESPACE . . . . . . . . . . . . . . . . . . . . . . 13 Frindell Expires 3 September 2026 [Page 2] Internet-Draft moq-moqpack March 2026 5.6.7. NAMESPACE_DONE . . . . . . . . . . . . . . . . . . . 13 5.6.8. TRACK_STATUS . . . . . . . . . . . . . . . . . . . . 13 5.6.9. SUBSCRIBE_OK . . . . . . . . . . . . . . . . . . . . 13 5.6.10. FETCH_OK . . . . . . . . . . . . . . . . . . . . . . 13 5.6.11. Parameter-Only Messages . . . . . . . . . . . . . . . 14 6. QPACK Encoding . . . . . . . . . . . . . . . . . . . . . . . 15 6.1. Compressed Block Format . . . . . . . . . . . . . . . . . 15 6.2. Indexing . . . . . . . . . . . . . . . . . . . . . . . . 15 6.3. MOQT Static Table Semantics . . . . . . . . . . . . . . . 16 6.3.1. Field Line Interpretation . . . . . . . . . . . . . . 16 6.4. Dynamic Table . . . . . . . . . . . . . . . . . . . . . . 17 6.4.1. Encoder Stream Instructions . . . . . . . . . . . . . 17 6.4.2. Parameter Value Encoding . . . . . . . . . . . . . . 17 6.4.3. Authorization Token Encoding . . . . . . . . . . . . 18 6.5. Decoding . . . . . . . . . . . . . . . . . . . . . . . . 18 7. Dynamic Table Management . . . . . . . . . . . . . . . . . . 19 7.1. Encoder Behavior . . . . . . . . . . . . . . . . . . . . 19 7.1.1. Known Received Count . . . . . . . . . . . . . . . . 19 7.1.2. Never-Indexed Literals . . . . . . . . . . . . . . . 19 7.1.3. Avoiding Flow Control Deadlocks . . . . . . . . . . . 20 7.2. Decoder Behavior . . . . . . . . . . . . . . . . . . . . 20 7.2.1. Decoder Instructions with Request IDs . . . . . . . . 20 8. Error Handling . . . . . . . . . . . . . . . . . . . . . . . 21 8.1. MOQPACK_DECOMPRESSION_FAILED . . . . . . . . . . . . . . 21 8.2. QPACK Errors . . . . . . . . . . . . . . . . . . . . . . 21 9. Security Considerations . . . . . . . . . . . . . . . . . . . 21 9.1. Dynamic Table State . . . . . . . . . . . . . . . . . . . 21 9.2. Compression Oracle Attacks . . . . . . . . . . . . . . . 22 9.3. Resource Exhaustion . . . . . . . . . . . . . . . . . . . 22 10. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 22 10.1. Setup Option Types . . . . . . . . . . . . . . . . . . . 22 10.2. Unidirectional Stream Types . . . . . . . . . . . . . . 22 10.3. Pseudo-Parameter Types . . . . . . . . . . . . . . . . . 23 10.4. Message Types . . . . . . . . . . . . . . . . . . . . . 23 10.5. Session Error Codes . . . . . . . . . . . . . . . . . . 24 11. References . . . . . . . . . . . . . . . . . . . . . . . . . 24 11.1. Normative References . . . . . . . . . . . . . . . . . . 25 11.2. Informative References . . . . . . . . . . . . . . . . . 25 Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . 25 Example Encoding . . . . . . . . . . . . . . . . . . . . . . . . 25 Scenario . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 First SUBSCRIBE . . . . . . . . . . . . . . . . . . . . . . . . 26 Subsequent SUBSCRIBEs to Same Track . . . . . . . . . . . . . . 27 SUBSCRIBE to Different Track, Same Namespace . . . . . . . . . 27 Code Point Summary . . . . . . . . . . . . . . . . . . . . . . . 28 Setup Options . . . . . . . . . . . . . . . . . . . . . . . . . 28 Stream Types . . . . . . . . . . . . . . . . . . . . . . . . . 28 Pseudo-Parameter Types . . . . . . . . . . . . . . . . . . . . 29 Frindell Expires 3 September 2026 [Page 3] Internet-Draft moq-moqpack March 2026 MOQPACK Message Types . . . . . . . . . . . . . . . . . . . . . 29 QPACK Library Adaptation Notes . . . . . . . . . . . . . . . . . 30 Static Table . . . . . . . . . . . . . . . . . . . . . . . . . 30 Prohibited Encodings . . . . . . . . . . . . . . . . . . . . . 31 Encoder Stream Instructions . . . . . . . . . . . . . . . . . . 31 Decoder Stream: Request IDs Instead of Stream IDs . . . . . . . 31 Entry Size Calculation . . . . . . . . . . . . . . . . . . . . 32 Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 32 1. Introduction Media over QUIC Transport (MOQT) [MOQT] control message fields and parameters can contain large values that are repeated across many messages within a session. The base MOQT specification transmits this information in full each time it appears, which can result in significant overhead. This document defines an extension that uses QPACK [QPACK] to compress MOQT message parameters. QPACK provides: * Dynamic table for referencing previously transmitted values * Static table with pre-defined common values * Stream blocking semantics suitable for QUIC By treating MOQT parameters as QPACK field lines, this extension enables efficient compression of repeated values while maintaining compatibility with QPACK's existing infrastructure. 1.1. Motivation Consider a session where a client sends 100 SUBSCRIBE messages, each carrying the same 500-byte authorization token. Without compression, this results in 50,000 bytes of token data. With QPACK compression, the token is transmitted once and subsequent references require only a few bytes, reducing total overhead to approximately 600 bytes. 2. Conventions and Definitions The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here. The terms "endpoint", "session", "publisher", and "subscriber" are defined in [MOQT]. Frindell Expires 3 September 2026 [Page 4] Internet-Draft moq-moqpack March 2026 3. Extension Negotiation This extension is negotiated during MOQT session establishment using Setup Options. CLIENT_SETUP and SERVER_SETUP messages always use standard MOQT encoding and are never MOQPACK compressed. 3.1. MOQT_QPACK_MAX_TABLE_CAPACITY The MOQT_QPACK_MAX_TABLE_CAPACITY setup option (Option Type 0x10) specifies the maximum size in bytes of the QPACK dynamic table the endpoint is willing to maintain for decoding. This corresponds to SETTINGS_QPACK_MAX_TABLE_CAPACITY in HTTP/3. The value is encoded as a variable-length integer. The default value is 0. QPACK compression is enabled when both endpoints send this parameter with a value greater than 0. If either endpoint omits this parameter or sends a value of 0, QPACK compression MUST NOT be used and control messages use the standard MOQT format. 3.2. MOQT_QPACK_BLOCKED_STREAMS The MOQT_QPACK_BLOCKED_STREAMS setup option (Option Type 0x11) specifies the maximum number of streams that can be blocked waiting for dynamic table updates. This corresponds to SETTINGS_QPACK_BLOCKED_STREAMS in HTTP/3. The value is encoded as a variable-length integer. The default value is 0, which prevents any stream from being blocked. When set to 0, encoders MUST NOT reference dynamic table entries that have not been acknowledged. This option is only meaningful when QPACK compression is enabled. 3.3. MOQT_QPACK_INDEX_SETUP_AUTH The MOQT_QPACK_INDEX_SETUP_AUTH setup option (Option Type 0x12) controls whether AUTHORIZATION TOKEN options from the Setup messages are implicitly inserted into the dynamic table. The value is encoded as a variable-length integer: * 0: Do not implicitly insert setup auth tokens (default) * 1: Implicitly insert setup auth tokens Frindell Expires 3 September 2026 [Page 5] Internet-Draft moq-moqpack March 2026 When either endpoint omits this option or sends 0, implicit insertion does not occur and endpoints that wish to reference auth tokens explicitly insert them via the encoder stream. This allows endpoints to authenticate the connection via setup auth tokens while still using Never-Indexed Literals for subsequent auth token references if desired. When both endpoints send MOQT_QPACK_INDEX_SETUP_AUTH with value 1, any AUTHORIZATION TOKEN options from the Setup messages are implicitly inserted into the dynamic table without requiring encoder stream instructions. Tokens from the Setup message, in the order they appeared, are inserted into the receiver's decoder dynamic table (indices 0, 1, 2, ...) This allows the client to immediately reference its setup auth token in the first SUBSCRIBE message using a dynamic table reference, without resending it on the encoder stream. The implicit entries count against the MOQT_QPACK_MAX_TABLE_CAPACITY limit. If the implicit entries would exceed the peer's advertised capacity, the excess entries (in reverse order) are not inserted and cannot be referenced. Encoder stream insertions after setup use indices starting after the implicit entries. For example, if CLIENT_SETUP contained 2 auth tokens, the first explicit insertion would be at index 2. 4. QPACK Streams When QPACK compression is negotiated, each endpoint opens two unidirectional streams for QPACK signaling. 4.1. Stream Types This extension defines two new MOQT unidirectional stream types: QPACK_ENCODER_STREAM (0x1f107a60): Carries QPACK encoder instructions from the endpoint that opens the stream. The format and semantics are defined in Section 4.3.1 of [QPACK]. QPACK_DECODER_STREAM (0x1f107a61): Carries QPACK decoder instructions from the endpoint that opens the stream. The format and semantics are defined in Section 4.4.1 of [QPACK]. Frindell Expires 3 September 2026 [Page 6] Internet-Draft moq-moqpack March 2026 4.2. Stream Initialization Each endpoint MUST open exactly one QPACK encoder stream and one QPACK decoder stream for QPACK use. These streams MUST be opened before sending any message with a Compressed Block. An endpoint MAY open these streams immediately after sending its Setup message if it included MOQT_QPACK_MAX_TABLE_CAPACITY with a non-zero value. If a receiving endpoint does not enable QPACK (omits the parameter or sends value 0), it MAY send STOP_SENDING on these streams; this is not an error and the streams SHOULD be reset. Note that implicitly-inserted dynamic table entries from Setup auth tokens (see Section 3.3) do not require encoder stream instructions. A Compressed Block MAY reference these implicit entries even if no encoder stream instructions have been sent. If an endpoint receives a Compressed Block that references a dynamic table entry beyond the implicit entries before receiving any encoder stream data, it MUST buffer the message until the required encoder instructions arrive or close the session with PROTOCOL_VIOLATION if buffering limits are exceeded. 4.3. Stream Lifetime QPACK encoder and decoder streams MUST remain open for the duration of the MOQT session. If either stream is closed after QPACK is negotiated, the endpoint MUST close the MOQT session with PROTOCOL_VIOLATION. 5. Compressed Message Formats 5.1. MOQPACK Flag Bit This extension uses a flag bit in the message type to indicate if QPACK is used. Bit 6 (0x40) of the message type indicates MOQPACK format: * Type & 0x40 == 0: Standard MOQT format * Type & 0x40 == 0x40: MOQPACK format For example: - SUBSCRIBE standard = 0x03 - SUBSCRIBE MOQPACK = 0x43 All MOQPACK message types listed in this document are reserved in the MOQT message type registry and MUST NOT be used for other purposes. Frindell Expires 3 September 2026 [Page 7] Internet-Draft moq-moqpack March 2026 When MOQPACK is negotiated, endpoints MUST accept both standard and MOQPACK formats for all applicable messages. An endpoint MAY send either format, but SHOULD prefer MOQPACK format to benefit from compression. When MOQPACK is NOT negotiated, endpoints MUST NOT send MOQPACK format messages and MUST close the session with PROTOCOL_VIOLATION if they receive one. In MOQPACK format, Track Namespace, Track Name, and Parameters are moved into a QPACK Compressed Block. Other message-specific fields including Properties remain unchanged. When the Compressed Block is the last field in the message, it extends to the end of the message payload (as determined by the message Length field) and no explicit Compressed Block Length is needed. When additional fields follow the Compressed Block (such as Properties), an explicit Compressed Block Length field is present to delimit the block. 5.2. Pseudo-Parameter Types The following pseudo-parameter types are reserved for encoding namespace and track name fields in the Compressed Block: +======+=========================+===================+ | Type | Name | Description | +======+=========================+===================+ | 0x0A | TRACK_NAMESPACE_ELEMENT | Single element of | | | | a namespace tuple | +------+-------------------------+-------------------+ | 0x0B | TRACK_NAMESPACE_SET | Full serialized | | | | namespace tuple | +------+-------------------------+-------------------+ | 0x0C | TRACK_NAME | Track Name | +------+-------------------------+-------------------+ Table 1 These pseudo-types use the same encoding as regular parameters: Literal with Static Name Reference for new values, or Indexed with Dynamic Table for previously-inserted values. 5.2.1. TRACK_NAMESPACE_SET Value Format The value of a TRACK_NAMESPACE_SET field uses the standard MOQT Track Namespace serialization as defined in [MOQT]: Frindell Expires 3 September 2026 [Page 8] Internet-Draft moq-moqpack March 2026 TRACK_NAMESPACE_SET Value { Number of Track Namespace Fields (vi64), Track Namespace Field (..) ... } Track Namespace Field { Track Namespace Field Length (vi64), Track Namespace Field Value (..) } Each Track Namespace Field Value MUST contain at least one byte, consistent with the requirement in [MOQT]. 5.3. Namespace Reconstruction A Track Namespace, Track Namespace Prefix or Track Namespace Suffix is reconstructed by assembling consecutive TRACK_NAMESPACE_ELEMENT and TRACK_NAMESPACE_SET field lines, which MUST appear first in the Compressed Block before TRACK_NAME or any parameters. TRACK_NAMESPACE_ELEMENT adds a single element to the namespace tuple. TRACK_NAMESPACE_SET appends all elements from a serialized tuple. These can be intermixed and appear in any combination. For example: Namespace ("conference", "room1", "audio"): Option A - All elements: TRACK_NAMESPACE_ELEMENT: "conference" TRACK_NAMESPACE_ELEMENT: "room1" TRACK_NAMESPACE_ELEMENT: "audio" Option B - Full set: TRACK_NAMESPACE_SET: ("conference", "room1", "audio") Option C - Mixed: TRACK_NAMESPACE_ELEMENT: "conference" TRACK_NAMESPACE_SET: ("room1", "audio") This allows encoders to maximize compression by inserting commonly- reused elements or partial tuples into the dynamic table. The message type determines the semantics of the assembled namespace: * SUBSCRIBE, PUBLISH, FETCH, TRACK_STATUS, PUBLISH_NAMESPACE: Full namespace * SUBSCRIBE_NAMESPACE: Namespace prefix Frindell Expires 3 September 2026 [Page 9] Internet-Draft moq-moqpack March 2026 * NAMESPACE, NAMESPACE_DONE: Namespace suffix 5.4. Field Ordering Namespace elements (TRACK_NAMESPACE_ELEMENT and TRACK_NAMESPACE_SET) MUST appear first in the Compressed Block, followed by TRACK_NAME (if present), followed by parameters in increasing order of parameter type. Within the namespace elements section, entries appear in the order they contribute to the namespace tuple and are not required to be in increasing order of type. TRACK_NAMESPACE_ELEMENT (0x0A) and TRACK_NAMESPACE_SET (0x0B) MAY be intermixed. Parameters (excluding pseudo-parameter types) MUST appear in increasing order of their parameter type. If parameters appear out of order, the receiver MUST close the session with PROTOCOL_VIOLATION. 5.5. Required Fields When decoding a Compressed Block, the receiver MUST verify that all required fields are present: * SUBSCRIBE, PUBLISH, TRACK_STATUS, Standalone FETCH: At least one namespace element (TRACK_NAMESPACE_ELEMENT or TRACK_NAMESPACE_SET) and TRACK_NAME * SUBSCRIBE_NAMESPACE, PUBLISH_NAMESPACE, NAMESPACE, NAMESPACE_DONE: At least one namespace element * Joining FETCH, parameter-only messages: No required pseudo- parameters An empty namespace (zero elements) is valid only if explicitly allowed by the message semantics. If a required field is missing, the receiver MUST close the session with PROTOCOL_VIOLATION. 5.6. MOQPACK Message Formats 5.6.1. SUBSCRIBE Frindell Expires 3 September 2026 [Page 10] Internet-Draft moq-moqpack March 2026 SUBSCRIBE Message (MOQPACK) { Type (vi64) = 0x43, Length (16), Request ID (vi64), Track Alias (vi64), Compressed Block (..) } The Compressed Block contains namespace elements (TRACK_NAMESPACE_ELEMENT and/or TRACK_NAMESPACE_SET), TRACK_NAME (0x0C), and any parameters (AUTHORIZATION_TOKEN, SUBSCRIBER_PRIORITY, etc.). 5.6.2. PUBLISH PUBLISH Message (MOQPACK) { Type (vi64) = 0x5D, Length (16), Request ID (vi64), Track Alias (vi64), Compressed Block Length (vi64), Compressed Block (..), Properties (..) } The Compressed Block contains namespace elements, TRACK_NAME, and any parameters. Properties remain outside the compressed block and use standard MOQT encoding, including IMMUTABLE_EXTENSIONS which are not QPACK compressed. 5.6.3. FETCH Frindell Expires 3 September 2026 [Page 11] Internet-Draft moq-moqpack March 2026 Standalone Fetch (MOQPACK) { Start Location (Location), End Location (Location), Compressed Block (..) } Joining Fetch (MOQPACK) { Joining Request ID (vi64), Join Type (vi64), Joining Start (vi64), Compressed Block (..) } FETCH Message (MOQPACK) { Type (vi64) = 0x56, Length (16), Request ID (vi64), Fetch Type (vi64), [Standalone (Standalone Fetch QPACK),] [Joining (Joining Fetch QPACK),] } For Standalone Fetch, the Compressed Block contains namespace elements, TRACK_NAME, and parameters. For Joining Fetch, the Compressed Block contains only parameters (the track is inherited from the joined subscription). 5.6.4. SUBSCRIBE_NAMESPACE SUBSCRIBE_NAMESPACE Message (MOQPACK) { Type (vi64) = 0x51, Length (16), Request ID (vi64), Subscribe Options (vi64), Compressed Block (..) } The Compressed Block contains namespace prefix elements and any parameters. 5.6.5. PUBLISH_NAMESPACE PUBLISH_NAMESPACE Message (MOQPACK) { Type (vi64) = 0x46, Length (16), Request ID (vi64), Compressed Block (..) } Frindell Expires 3 September 2026 [Page 12] Internet-Draft moq-moqpack March 2026 The Compressed Block contains namespace elements and any parameters. 5.6.6. NAMESPACE NAMESPACE Message (MOQPACK) { Type (vi64) = 0x48, Length (16), Compressed Block (..) } The Compressed Block contains namespace suffix elements. This message has no parameters. 5.6.7. NAMESPACE_DONE NAMESPACE_DONE Message (MOQPACK) { Type (vi64) = 0x4E, Length (16), Compressed Block (..) } The Compressed Block contains namespace suffix elements. This message has no parameters. 5.6.8. TRACK_STATUS TRACK_STATUS uses the same format as SUBSCRIBE but with type 0x4D. The Compressed Block contains namespace elements, TRACK_NAME, and any applicable parameters. 5.6.9. SUBSCRIBE_OK SUBSCRIBE_OK Message (MOQPACK) { Type (vi64) = 0x44, Length (16), Request ID (vi64), Compressed Block Length (vi64), Compressed Block (..), Properties (..) } The Compressed Block contains only parameters. Properties remain outside the Compressed Block and use standard MOQT encoding. The Compressed Block Length is required because Properties consume the remainder of the message. 5.6.10. FETCH_OK Frindell Expires 3 September 2026 [Page 13] Internet-Draft moq-moqpack March 2026 FETCH_OK Message (MOQPACK) { Type (vi64) = 0x58, Length (16), Request ID (vi64), Compressed Block Length (vi64), Compressed Block (..), Properties (..) } The Compressed Block contains only parameters. Properties remain outside the Compressed Block and use standard MOQT encoding. The Compressed Block Length is required because Properties consume the remainder of the message. 5.6.11. Parameter-Only Messages The following messages have parameters but no namespace, track name, or trailing properties. When MOQPACK is negotiated, these messages MAY use MOQPACK format with the 0x40 flag bit set. The MOQPACK format replaces the standard Parameters field with a Compressed Block that consumes the remainder of the message: +===============+==============+================+ | Standard Type | MOQPACK Type | Message | +===============+==============+================+ | 0x02 | 0x42 | REQUEST_UPDATE | +---------------+--------------+----------------+ | 0x05 | 0x45 | REQUEST_ERROR | +---------------+--------------+----------------+ | 0x07 | 0x47 | REQUEST_OK | +---------------+--------------+----------------+ | 0x1E | 0x5E | PUBLISH_OK | +---------------+--------------+----------------+ Table 2 Parameter-Only Message (MOQPACK) { Type (vi64) = | 0x40, Length (16), [Message-specific fields...], Compressed Block (..) } The Compressed Block contains only parameters (no pseudo-parameter types). Message-specific fields (Request ID, error codes, etc.) remain unchanged. Frindell Expires 3 September 2026 [Page 14] Internet-Draft moq-moqpack March 2026 6. QPACK Encoding This extension uses QPACK's wire encoding formats exactly as specified in [QPACK]. The only difference is the interpretation of static table references: instead of indexing into the HTTP static table of string name-value pairs, the static table index IS the MOQT parameter type. This allows existing QPACK encoder/decoder implementations to be reused with minimal modification. 6.1. Compressed Block Format Each Compressed Block begins with the standard QPACK encoded field section prefix as defined in Section 4.5.1 of [QPACK]: Compressed Block { Required Insert Count (8+), Sign and Delta Base (8+), Encoded Field Lines (..) } Required Insert Count: Encoded as specified in Section 4.5.1.1 of [QPACK]. Indicates the minimum dynamic table state needed to decode this block. A value of 0 means the block has no dynamic table references. Base: Encoded as a sign bit and Delta Base as specified in Section 4.5.1.2 of [QPACK]. Used to resolve relative indices in field line representations. 6.2. Indexing Dynamic table references in field lines use relative indexing as specified in [QPACK] Section 3.2.5. A relative index of 0 refers to the entry with absolute index equal to Base - 1. Encoders and decoders MUST use relative indices, not absolute indices, in Compressed Blocks. Post-Base indexing (Section 3.2.6 of [QPACK]) MAY be used for entries inserted after the Base. This enables single-pass encoding where the encoder inserts entries while encoding a field section and references them using Post-Base indices. Frindell Expires 3 September 2026 [Page 15] Internet-Draft moq-moqpack March 2026 6.3. MOQT Static Table Semantics In standard QPACK, a static table index retrieves a predefined (name, value) pair. In this extension, the static table conceptually contains entries where the "name" is the parameter type integer and there is no predefined value. The static table index equals the MOQT parameter type: For example: * Static index 0x02 represents DELIVERY_TIMEOUT * Static index 0x03 represents AUTHORIZATION_TOKEN * Static index 0x0A represents TRACK_NAMESPACE_ELEMENT * Static index 0x0C represents TRACK_NAME * Static index 0x20 represents SUBSCRIBER_PRIORITY This means any valid MOQT parameter type can be referenced by static index without requiring pre-registration in a table. 6.3.1. Field Line Interpretation In QPACK field line encodings, the T bit selects between static table (T=1) and dynamic table (T=0). Since MOQT parameter types are integers that map directly to static table indices, the following encodings are used: Literal Field Line With Static Name Reference (T=1): The Name Index is the MOQT parameter type. The Value field contains the parameter value. Use this to send a parameter value. Indexed Field Line with Dynamic Table (T=0): References the dynamic table using a relative index. The retrieved entry contains a complete MOQT parameter (type and value). Indexed Field Line with Post-Base Index: References a dynamic table entry inserted after the Base. Used for single-pass encoding. See [QPACK] Section 4.5.3. The following QPACK field line encodings are prohibited: Indexed Field Line with Static Table (T=1): PROHIBITED. The MOQT static table has no predefined values. Literal Field Line With Dynamic Name Reference (T=0): PROHIBITED. Parameter types are always known integers; there is no need to reference the dynamic table for a parameter type. Literal Field Line with Post-Base Name Reference: PROHIBITED. Parameter types are always known integers; there is no need to reference the dynamic table for a parameter type. Frindell Expires 3 September 2026 [Page 16] Internet-Draft moq-moqpack March 2026 Literal Field Line With Literal Name: PROHIBITED. Parameter types are integers, never string literals. Huffman-encoded string literals (H=1): PROHIBITED. The CPU cost outweighs the minimal space savings for typical MOQT values. Encoders MUST set the H bit to 0 for all string literals. Receivers MUST treat prohibited encodings as a PROTOCOL_VIOLATION. 6.4. Dynamic Table Dynamic table entries store complete MOQT parameters (type and value). The entry size calculation follows [QPACK] Section 3.2.1: the size of an entry is the sum of its name size, value size, and 32 bytes of overhead. This extension uses a fixed name size of 4 bytes for the parameter type regardless of its encoded length. 6.4.1. Encoder Stream Instructions Set Dynamic Table Capacity: Sets the dynamic table capacity up to the peer's MOQT_QPACK_MAX_TABLE_CAPACITY. Encoders MAY reduce capacity dynamically. See [QPACK] Section 4.3.1. Insert With Static Name Reference (T=1): The Name Index is the MOQT parameter type. Inserts a new dynamic table entry with that parameter type and the provided value. Duplicate: Duplicates an existing dynamic table entry at a new index. Useful when an entry is near eviction but still frequently referenced. See [QPACK] Section 4.3.4. Insert With Dynamic Name Reference (T=0): PROHIBITED. Parameter types are always known integers. Insert With Literal Name: PROHIBITED. Parameter types are integers, never strings. Receivers MUST close the session with PROTOCOL_VIOLATION if a prohibited encoder instruction is received. 6.4.2. Parameter Value Encoding QPACK values contain the raw parameter value bytes without any MOQT length prefix. The QPACK value length field serves as the length for binary values. For binary parameters (odd parameter types in MOQT): The QPACK value Frindell Expires 3 September 2026 [Page 17] Internet-Draft moq-moqpack March 2026 contains the raw binary bytes. The QPACK value length replaces the MOQT Length field. No length prefix is included in the value. For integer parameters (even parameter types in MOQT): The QPACK value contains the varint-encoded integer. Note that this encoding carries redundant length information: the QPACK value length specifies the byte count, while the varint encoding is self-delimiting. If the varint-encoded length does not match the QPACK value length, the receiver MUST close the session with PROTOCOL_VIOLATION. For example, DELIVERY_TIMEOUT with value 200: ~~~ QPACK Value Length: 2 QPACK Value: 0xC8 0x01 (varint encoding of 200) ~~~ The receiver decodes the varint and verifies it consumed exactly 2 bytes. 6.4.3. Authorization Token Encoding The AUTHORIZATION TOKEN parameter value contains the Token structure: Token Value = Token Type (vi64) || Token Payload (..) For example, a JWT token (Token Type 1) is encoded as: Literal Field Line With Name Reference: Name Index: 0x03 (AUTHORIZATION_TOKEN) Value: 0x01 || "eyJhbGciOiJIUzI1NiIs..." When this token is inserted into the dynamic table, subsequent references use only a single-byte Indexed Field Line. 6.5. Decoding When receiving a message with a Compressed Block, the receiver: 1. Parses fixed message fields (Request ID, Track Alias, etc.) 2. If a Compressed Block is present: a. Waits for any referenced dynamic table entries to become available, subject to MOQT_QPACK_BLOCKED_STREAMS limits b. Decodes the QPACK Compressed Block to recover namespace elements, track name, and parameters 3. Processes the fully decoded message If QPACK decoding fails, the receiver MUST close the session with MOQPACK_DECOMPRESSION_FAILED. Frindell Expires 3 September 2026 [Page 18] Internet-Draft moq-moqpack March 2026 The total size of the decompressed message fields (the sum of all parameter values, namespace elements, and track name, excluding interior length fields) MUST NOT exceed 65535 bytes. If a decompressed message exceeds this limit, the receiver MUST close the session with MOQPACK_DECOMPRESSION_FAILED. 7. Dynamic Table Management 7.1. Encoder Behavior Encoders SHOULD insert frequently-used parameter values into the dynamic table. Authorization tokens, Track Namespace Elements and Track names that will be reused across multiple messages are prime candidates for insertion. Short values like brief track names ("audio", "video") MAY be sent as literals rather than inserted, since the overhead of insertion and indexed reference is similar to sending the literal value. Insertion is more beneficial for: - Long values (large auth tokens, long namespace elements) - Values that will be reused across multiple messages (namespace elements shared by many tracks, auth tokens used for many subscriptions) Encoders MUST respect the peer's MOQT_QPACK_MAX_TABLE_CAPACITY and MOQT_QPACK_BLOCKED_STREAMS limits when making insertion and reference decisions. Encoders SHOULD use the QPACK duplicate instruction when a dynamic table entry is at risk of eviction but is still frequently referenced. 7.1.1. Known Received Count Encoders track the Known Received Count as specified in [QPACK] Section 2.1.4 to determine which entries can be referenced without blocking. Encoders MUST only reference dynamic table entries with absolute index less than the Known Received Count when the number of streams that would be blocked by the reference equals MOQT_QPACK_BLOCKED_STREAMS. 7.1.2. Never-Indexed Literals The 'N' bit in Literal Field Line representations signals that a value MUST NOT be indexed by intermediaries. Encoders MAY set the 'N' bit for sensitive values when: - The value should not be cached by relays - The value has low entropy and is vulnerable to compression attacks Frindell Expires 3 September 2026 [Page 19] Internet-Draft moq-moqpack March 2026 Note that when MOQT_QPACK_INDEX_SETUP_AUTH is enabled, setup auth tokens are implicitly inserted into the dynamic table (see Section 3.3). Endpoints that require 'N' bit semantics for auth tokens MUST NOT enable MOQT_QPACK_INDEX_SETUP_AUTH and SHOULD instead send tokens as Never-Indexed Literals in each message. Intermediaries that re-encode MOQT messages MUST preserve the 'N' bit semantics: values encoded with N=1 MUST NOT be inserted into the dynamic table. 7.1.3. Avoiding Flow Control Deadlocks Writing large encoder instructions can cause deadlocks if the decoder withholds flow control credit until the instruction is complete. To avoid this, encoders SHOULD NOT write an encoder instruction unless sufficient stream and connection flow-control credit is available for the entire instruction. If sufficient credit is not available, encoders SHOULD use literal encodings instead. See [QPACK] Section 2.1.3. 7.2. Decoder Behavior Decoders MUST process encoder instructions from the QPACK encoder stream before processing any message that might reference those insertions. Decoders MUST send Section Acknowledgment instructions on the QPACK decoder stream after successfully decoding a Compressed Block that references the dynamic table (Required Insert Count > 0). Compressed Blocks that contain only Literal Field Lines with Static Name References do not require acknowledgment. 7.2.1. Decoder Instructions with Request IDs QPACK decoder instructions that reference streams (Section Acknowledgment, Stream Cancellation) use Request IDs instead of QUIC Stream IDs. This allows MOQT to operate over WebTransport where QUIC Stream IDs are not exposed to the application. Section Acknowledgment: Carries a Request ID. Acknowledges successful decoding of a Compressed Block that referenced the dynamic table. For streams with multiple such Compressed Blocks (e.g., SUBSCRIBE_NAMESPACE response stream with multiple NAMESPACE messages referencing the dynamic table), successive Section Acknowledgments for the same Request ID acknowledge successive Compressed Blocks in the order they were sent. Compressed Blocks with no dynamic table references are not counted. Frindell Expires 3 September 2026 [Page 20] Internet-Draft moq-moqpack March 2026 Stream Cancellation: Carries a Request ID. Indicates the stream was cancelled before the Compressed Block(s) could be decoded. The encoder MUST NOT count references from that stream when determining eviction eligibility. Insert Count Increment: Unchanged from [QPACK]. Carries an increment value, no Request ID. The encoder tracks how many Compressed Blocks it has sent for each Request ID. When it receives a Section Acknowledgment for a Request ID, it knows which Compressed Block was acknowledged based on the count. 8. Error Handling 8.1. MOQPACK_DECOMPRESSION_FAILED This document defines a new MOQT session error code: MOQPACK_DECOMPRESSION_FAILED (0xTBD): A QPACK Compressed Block could not be decoded, or the decompressed message exceeded implementation limits. This is always a session error; the endpoint MUST close the MOQT session. 8.2. QPACK Errors QPACK decoding errors (as defined in Section 6 of [QPACK]) result in session termination. The specific mapping is: +============================+==============================+ | QPACK Error | MOQT Session Error | +============================+==============================+ | QPACK_DECOMPRESSION_FAILED | MOQPACK_DECOMPRESSION_FAILED | +----------------------------+------------------------------+ | QPACK_ENCODER_STREAM_ERROR | PROTOCOL_VIOLATION | +----------------------------+------------------------------+ | QPACK_DECODER_STREAM_ERROR | PROTOCOL_VIOLATION | +----------------------------+------------------------------+ Table 3 9. Security Considerations 9.1. Dynamic Table State The QPACK dynamic table maintains state across messages. An attacker with knowledge of dynamic table contents could potentially: Frindell Expires 3 September 2026 [Page 21] Internet-Draft moq-moqpack March 2026 * Determine which authorization tokens have been used * Infer subscription patterns from parameter compression ratios Implementations SHOULD consider these privacy implications when deciding which values to insert into the dynamic table. 9.2. Compression Oracle Attacks As with HTTP compression, implementers need to take care to avoid compression oracle attacks where an attacker can infer secret values by observing compressed message sizes. Applications SHOULD NOT mix attacker-controlled data with secret authorization tokens in the same field section. 9.3. Resource Exhaustion Endpoints MUST enforce the negotiated table capacity limits to prevent resource exhaustion attacks. An endpoint that attempts to exceed these limits causes a session error. 10. IANA Considerations 10.1. Setup Option Types This document registers the following Setup Option Types in the "MOQT Setup Options" registry: +================+===============================+===============+ | Parameter Type | Parameter Name | Specification | +================+===============================+===============+ | 0x10 | MOQT_QPACK_MAX_TABLE_CAPACITY | Section 3 | +----------------+-------------------------------+---------------+ | 0x11 | MOQT_QPACK_BLOCKED_STREAMS | Section 3 | +----------------+-------------------------------+---------------+ | 0x12 | MOQT_QPACK_INDEX_SETUP_AUTH | Section 3 | +----------------+-------------------------------+---------------+ Table 4 10.2. Unidirectional Stream Types This document registers the following unidirectional stream types in the "MOQT Stream Types" registry: Frindell Expires 3 September 2026 [Page 22] Internet-Draft moq-moqpack March 2026 +=============+======================+===============+ | Stream Type | Name | Specification | +=============+======================+===============+ | 0x1f107a60 | QPACK_ENCODER_STREAM | Section 4.1 | +-------------+----------------------+---------------+ | 0x1f107a61 | QPACK_DECODER_STREAM | Section 4.1 | +-------------+----------------------+---------------+ Table 5 10.3. Pseudo-Parameter Types This document registers the following pseudo-parameter types in the "MOQT Message Parameters" registry. These types are reserved for use in QPACK Compressed Blocks and MUST NOT appear in standard Parameters fields. +================+=========================+===============+ | Parameter Type | Parameter Name | Specification | +================+=========================+===============+ | 0x0A | TRACK_NAMESPACE_ELEMENT | Section 5.2 | +----------------+-------------------------+---------------+ | 0x0B | TRACK_NAMESPACE_SET | Section 5.2 | +----------------+-------------------------+---------------+ | 0x0C | TRACK_NAME | Section 5.2 | +----------------+-------------------------+---------------+ Table 6 10.4. Message Types This document reserves the following message types in the "MOQT Message Types" registry for use as MOQPACK-format messages: Frindell Expires 3 September 2026 [Page 23] Internet-Draft moq-moqpack March 2026 +==============+=============================+===============+ | Message Type | Name | Specification | +==============+=============================+===============+ | 0x42 | MOQPACK REQUEST_UPDATE | Section 5.6 | +--------------+-----------------------------+---------------+ | 0x43 | MOQPACK SUBSCRIBE | Section 5.6 | +--------------+-----------------------------+---------------+ | 0x44 | MOQPACK SUBSCRIBE_OK | Section 5.6 | +--------------+-----------------------------+---------------+ | 0x45 | MOQPACK REQUEST_ERROR | Section 5.6 | +--------------+-----------------------------+---------------+ | 0x46 | MOQPACK PUBLISH_NAMESPACE | Section 5.6 | +--------------+-----------------------------+---------------+ | 0x47 | MOQPACK REQUEST_OK | Section 5.6 | +--------------+-----------------------------+---------------+ | 0x48 | MOQPACK NAMESPACE | Section 5.6 | +--------------+-----------------------------+---------------+ | 0x4D | MOQPACK TRACK_STATUS | Section 5.6 | +--------------+-----------------------------+---------------+ | 0x4E | MOQPACK NAMESPACE_DONE | Section 5.6 | +--------------+-----------------------------+---------------+ | 0x51 | MOQPACK SUBSCRIBE_NAMESPACE | Section 5.6 | +--------------+-----------------------------+---------------+ | 0x56 | MOQPACK FETCH | Section 5.6 | +--------------+-----------------------------+---------------+ | 0x58 | MOQPACK FETCH_OK | Section 5.6 | +--------------+-----------------------------+---------------+ | 0x5D | MOQPACK PUBLISH | Section 5.6 | +--------------+-----------------------------+---------------+ | 0x5E | MOQPACK PUBLISH_OK | Section 5.6 | +--------------+-----------------------------+---------------+ Table 7 10.5. Session Error Codes This document registers the following session error code in the "MOQT Session Error Codes" registry: +============+==============================+===============+ | Error Code | Name | Specification | +============+==============================+===============+ | 0xTBD | MOQPACK_DECOMPRESSION_FAILED | Section 8.1 | +------------+------------------------------+---------------+ Table 8 11. References Frindell Expires 3 September 2026 [Page 24] Internet-Draft moq-moqpack March 2026 11.1. Normative References [MOQT] Nandakumar, S., Vasiliev, V., Swett, I., and A. Frindell, "Media over QUIC Transport", Work in Progress, Internet- Draft, draft-ietf-moq-transport-16, 13 January 2026, . [QPACK] Krasic, C., Bishop, M., and A. Frindell, Ed., "QPACK: Field Compression for HTTP/3", RFC 9204, DOI 10.17487/RFC9204, June 2022, . [QUIC] Iyengar, J., Ed. and M. Thomson, Ed., "QUIC: A UDP-Based Multiplexed and Secure Transport", RFC 9000, DOI 10.17487/RFC9000, May 2021, . [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, . [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, . 11.2. Informative References [HPACK] Peon, R. and H. Ruellan, "HPACK: Header Compression for HTTP/2", RFC 7541, DOI 10.17487/RFC7541, May 2015, . Acknowledgments The QPACK specification [QPACK] provides the foundation for this work. The design of HTTP/3 header compression informed many decisions in this document. Claude, by Anthropic, assisted in drafting this document. Example Encoding This appendix provides an example of QPACK-compressed MOQT messages, demonstrating the Required Insert Count, Base, and relative indexing. Frindell Expires 3 September 2026 [Page 25] Internet-Draft moq-moqpack March 2026 Scenario A client sends three SUBSCRIBE messages to the same track with the same authorization token: * Track Namespace: ("conference", "room42") * Track Name: "audio" * Token Type: 1 (e.g., JWT) * Token Value: "eyJhbGciOiJIUzI1NiIs..." (500 bytes) The auth token was sent in CLIENT_SETUP and is implicitly inserted at dynamic table absolute index 0 after QPACK negotiation succeeds. First SUBSCRIBE The encoder inserts namespace elements on the encoder stream. The short track name "audio" is sent as a literal rather than inserted: Encoder Stream: Insert With Static Name Reference Name Index: 0x0A (TRACK_NAMESPACE_ELEMENT) Value: "conference" Insert With Static Name Reference Name Index: 0x0A (TRACK_NAMESPACE_ELEMENT) Value: "room42" Dynamic table state after insertions: +================+=========================+========================+ | Absolute Index | Parameter Type | Value | +================+=========================+========================+ | 0 | AUTH_TOKEN (implicit) | Token Type | | | | 1, "eyJ..." | +----------------+-------------------------+------------------------+ | 1 | TRACK_NAMESPACE_ELEMENT | "conference" | +----------------+-------------------------+------------------------+ | 2 | TRACK_NAMESPACE_ELEMENT | "room42" | +----------------+-------------------------+------------------------+ Table 9 The encoder sends the SUBSCRIBE with Required Insert Count = 3 and Base = 3: Frindell Expires 3 September 2026 [Page 26] Internet-Draft moq-moqpack March 2026 SUBSCRIBE Message: Type: 0x43 Request ID: 1 Track Alias: 100 Compressed Block: Required Insert Count: 3 (encoded per RFC 9204 Section 4.5.1.1) Base: Sign=0, Delta=0 (Base = Required Insert Count = 3) Indexed Field Line (Dynamic, relative index 1) // abs 1 = "conference" Indexed Field Line (Dynamic, relative index 0) // abs 2 = "room42" Literal Field Line (Static Name 0x0C, Value "audio") // TRACK_NAME Indexed Field Line (Dynamic, relative index 2) // abs 0 = AUTH_TOKEN Relative index calculation: relative = Base - 1 - absolute * "conference": relative = 3 - 1 - 1 = 1 * "room42": relative = 3 - 1 - 2 = 0 * AUTH_TOKEN: relative = 3 - 1 - 0 = 2 Compressed Block: ~12 bytes (including prefix and literal track name) Uncompressed equivalent: ~526 bytes Subsequent SUBSCRIBEs to Same Track No encoder stream instructions needed; namespace elements are in the table, track name is sent as literal again: SUBSCRIBE Message: Type: 0x43 Request ID: 2 Track Alias: 101 Compressed Block: Required Insert Count: 3 Base: Sign=0, Delta=0 Indexed Field Line (Dynamic, relative index 1) // "conference" Indexed Field Line (Dynamic, relative index 0) // "room42" Literal Field Line (Static Name 0x0C, Value "audio") // TRACK_NAME Indexed Field Line (Dynamic, relative index 2) // AUTH_TOKEN Each subsequent SUBSCRIBE to the same track: ~12 bytes instead of ~526 bytes. SUBSCRIBE to Different Track, Same Namespace The track name "video" is also short, so we send it as a literal. No encoder stream instructions needed: Frindell Expires 3 September 2026 [Page 27] Internet-Draft moq-moqpack March 2026 SUBSCRIBE Message: Type: 0x43 Request ID: 3 Track Alias: 102 Compressed Block: Required Insert Count: 3 Base: Sign=0, Delta=0 Indexed Field Line (Dynamic, relative index 1) // "conference" Indexed Field Line (Dynamic, relative index 0) // "room42" Literal Field Line (Static Name 0x0C, Value "video") // TRACK_NAME Indexed Field Line (Dynamic, relative index 2) // AUTH_TOKEN The namespace elements are reused; the different track name is sent as a literal. Code Point Summary This appendix summarizes all code points defined or used by this extension. Setup Options +======+===============================+ | Type | Name | +======+===============================+ | 0x10 | MOQT_QPACK_MAX_TABLE_CAPACITY | +------+-------------------------------+ | 0x11 | MOQT_QPACK_BLOCKED_STREAMS | +------+-------------------------------+ | 0x12 | MOQT_QPACK_INDEX_SETUP_AUTH | +------+-------------------------------+ Table 10 Stream Types +============+======================+ | Type | Name | +============+======================+ | 0x1f107a60 | QPACK_ENCODER_STREAM | +------------+----------------------+ | 0x1f107a61 | QPACK_DECODER_STREAM | +------------+----------------------+ Table 11 Frindell Expires 3 September 2026 [Page 28] Internet-Draft moq-moqpack March 2026 Pseudo-Parameter Types +======+=========================+ | Type | Name | +======+=========================+ | 0x0A | TRACK_NAMESPACE_ELEMENT | +------+-------------------------+ | 0x0B | TRACK_NAMESPACE_SET | +------+-------------------------+ | 0x0C | TRACK_NAME | +------+-------------------------+ Table 12 MOQPACK Message Types The MOQPACK flag bit (0x40) is OR'd with standard MOQT message types: Frindell Expires 3 September 2026 [Page 29] Internet-Draft moq-moqpack March 2026 +==========+=========+=====================+ | Standard | MOQPACK | Message | +==========+=========+=====================+ | 0x02 | 0x42 | REQUEST_UPDATE | +----------+---------+---------------------+ | 0x03 | 0x43 | SUBSCRIBE | +----------+---------+---------------------+ | 0x04 | 0x44 | SUBSCRIBE_OK | +----------+---------+---------------------+ | 0x05 | 0x45 | REQUEST_ERROR | +----------+---------+---------------------+ | 0x06 | 0x46 | PUBLISH_NAMESPACE | +----------+---------+---------------------+ | 0x07 | 0x47 | REQUEST_OK | +----------+---------+---------------------+ | 0x08 | 0x48 | NAMESPACE | +----------+---------+---------------------+ | 0x0D | 0x4D | TRACK_STATUS | +----------+---------+---------------------+ | 0x0E | 0x4E | NAMESPACE_DONE | +----------+---------+---------------------+ | 0x11 | 0x51 | SUBSCRIBE_NAMESPACE | +----------+---------+---------------------+ | 0x16 | 0x56 | FETCH | +----------+---------+---------------------+ | 0x18 | 0x58 | FETCH_OK | +----------+---------+---------------------+ | 0x1D | 0x5D | PUBLISH | +----------+---------+---------------------+ | 0x1E | 0x5E | PUBLISH_OK | +----------+---------+---------------------+ Table 13 QPACK Library Adaptation Notes This appendix summarizes the modifications needed to use a standard QPACK library (designed for HTTP/3) with this extension. Static Table Standard QPACK libraries include a static table of 99 predefined HTTP header (name, value) pairs. For MOQPACK, the static table is reinterpreted: the static table index directly represents the MOQT parameter type integer, and there are no predefined values. Implementations need to replace or bypass the HTTP static table. A simple approach is to treat the static table as a mapping from index to a 4-byte big-endian representation of the parameter type, with no Frindell Expires 3 September 2026 [Page 30] Internet-Draft moq-moqpack March 2026 predefined value. Prohibited Encodings Standard QPACK supports all field line representations. MOQPACK prohibits several (see Section 6.3.1). Implementations should configure the encoder to only emit: * Literal Field Line With Static Name Reference (for new parameter values) * Indexed Field Line with Dynamic Table (for previously-inserted values) * Indexed Field Line with Post-Base Index And should configure the decoder to reject: * Indexed Field Line with Static Table * Literal Field Line With Dynamic Name Reference * Literal Field Line with Post-Base Name Reference * Literal Field Line With Literal Name * Huffman-encoded string literals (H=1) Encoder Stream Instructions Only two insertion forms are used: * Insert With Static Name Reference * Duplicate Insert With Dynamic Name Reference and Insert With Literal Name are not used. Decoder Stream: Request IDs Instead of Stream IDs Standard QPACK decoder instructions (Section Acknowledgment, Stream Cancellation) carry QUIC stream IDs. In MOQPACK, these carry MOQT Request IDs instead (see Section 7.2.1). The encoder needs to track Compressed Blocks per Request ID rather than per stream ID. This also enables MOQPACK to operate over WebTransport where QUIC stream IDs are not exposed to the application. Frindell Expires 3 September 2026 [Page 31] Internet-Draft moq-moqpack March 2026 Entry Size Calculation The name size for all entries is fixed at 4 bytes (rather than the variable-length header name strings used in HTTP). The 32-byte per- entry overhead from [QPACK] Section 3.2.1 still applies. Author's Address Alan Frindell Meta Email: afrind@meta.com Frindell Expires 3 September 2026 [Page 32]