QPACK Compression for MoQ Transport
draft-frindell-moq-moqpack-00
This document is an Internet-Draft (I-D).
Anyone may submit an I-D to the IETF.
This I-D is not endorsed by the IETF and has no formal standing in the
IETF standards process.
| Document | Type | Active Internet-Draft (individual) | |
|---|---|---|---|
| Author | Alan Frindell | ||
| Last updated | 2026-03-02 | ||
| RFC stream | (None) | ||
| Intended RFC status | (None) | ||
| Formats | |||
| Stream | Stream state | (No stream defined) | |
| Consensus boilerplate | Unknown | ||
| RFC Editor Note | (None) | ||
| IESG | IESG state | I-D Exists | |
| Telechat date | (None) | ||
| Responsible AD | (None) | ||
| Send notices to | (None) |
draft-frindell-moq-moqpack-00
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) = <standard type> | 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,
<https://datatracker.ietf.org/doc/html/draft-ietf-moq-
transport-16>.
[QPACK] Krasic, C., Bishop, M., and A. Frindell, Ed., "QPACK:
Field Compression for HTTP/3", RFC 9204,
DOI 10.17487/RFC9204, June 2022,
<https://www.rfc-editor.org/rfc/rfc9204>.
[QUIC] Iyengar, J., Ed. and M. Thomson, Ed., "QUIC: A UDP-Based
Multiplexed and Secure Transport", RFC 9000,
DOI 10.17487/RFC9000, May 2021,
<https://www.rfc-editor.org/rfc/rfc9000>.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119,
DOI 10.17487/RFC2119, March 1997,
<https://www.rfc-editor.org/rfc/rfc2119>.
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
May 2017, <https://www.rfc-editor.org/rfc/rfc8174>.
11.2. Informative References
[HPACK] Peon, R. and H. Ruellan, "HPACK: Header Compression for
HTTP/2", RFC 7541, DOI 10.17487/RFC7541, May 2015,
<https://www.rfc-editor.org/rfc/rfc7541>.
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]