MoQT explained
Track Namespace vs Track Name
In Media over QUIC Transport (MoQT), the Track Namespace is an
ordered tuple of byte-string components that groups related tracks —
e.g. ["chat", "room1"].
The Track Name is a single byte string that identifies one track within that
namespace — e.g. "messages".
The namespace is the folder; the name is the file. Together they form the
Full Track Name, which uniquely identifies a track.
The key behavioral difference: the namespace supports prefix matching for discovery, while the name is always matched exactly.
Applies to draft-ietf-moq-transport drafts 07–23.
Side by side
| Track Namespace | Track Name | |
|---|---|---|
| What it is | An ordered tuple of up to 32 byte-string components that groups related tracks | A single byte string that identifies one track within a namespace |
| Wire type | Tuple (count + length-prefixed components) | Length-prefixed bytes |
| Example | ["chat", "room1"] | "messages" |
| Cardinality | One namespace holds many tracks | One name per track inside its namespace |
| Used for | Discovery & announcement — prefix matching in SUBSCRIBE_NAMESPACE; carried in PUBLISH_NAMESPACE and NAMESPACE | Addressing a specific track in SUBSCRIBE / FETCH / PUBLISH |
| Supports prefix matching | Yes — a prefix tuple matches every namespace that starts with it | No — matched exactly |
The Full Track Name
Neither the namespace nor the name is unique on its own. Two different namespaces can each contain a
track called "video",
and one namespace contains many differently-named tracks. What uniquely identifies a track is the
pair — the Full Track Name:
Full Track Name = ( Track Namespace , Track Name )
= ( ["sports","live","game42"] , "video" ) Because repeating a full namespace tuple and name on every object would be wasteful, MoQT assigns each subscribed track a compact integer Track Alias. Control messages carry the Full Track Name; the subgroup streams and datagrams that follow reference the track by its alias. The subscriber picks the alias in SUBSCRIBE in drafts 07–11; from draft-12 the publisher assigns it, in SUBSCRIBE_OK or PUBLISH. The control message type reference lists which messages exist in which draft, and each row links to that draft's byte-level layout.
Where each one appears
The distinction is easiest to see by which control messages use which field:
| Message | Drafts | Track Namespace | Track Name | Role |
|---|---|---|---|---|
| SUBSCRIBE | 07–23 | Full tuple | Exact name | Identifies the one track to receive objects from |
| FETCH | 07–23 | Full tuple | Exact name | Identifies the track to pull historical objects from (a standalone fetch) |
| PUBLISH | 12–23 | Full tuple | Exact name | A publisher offers a specific track to a subscriber |
| SUBSCRIBE_NAMESPACE | 13–23 | Prefix tuple | — (not used) | Registers interest in a namespace prefix (SUBSCRIBE_ANNOUNCES in drafts 07–12) |
| PUBLISH_NAMESPACE | 14–23 | Full tuple | — (not used) | A publisher advertises that it has tracks in a namespace (ANNOUNCE in drafts 07–13) |
| NAMESPACE | 16–23 | Suffix tuple | — (not used) | The response to SUBSCRIBE_NAMESPACE — carries the namespace suffix after your prefix |
Note the last three rows: namespace messages use only the namespace, never a track name.
Why the namespace is a tuple: prefix matching
The namespace being an ordered tuple — rather than a flat string — is what makes discovery work. A
subscriber sends SUBSCRIBE_NAMESPACE
with a prefix tuple, and the relay announces every namespace that begins with it —
as NAMESPACE
messages carrying the suffix after your prefix (drafts 16–23):
TX SUBSCRIBE_NAMESPACE prefix = ["sports"]
RX REQUEST_OK
RX NAMESPACE ["live","game42"] ✓ matches → suffix after ["sports"]
RX NAMESPACE ["vod","game17"] ✓ matches
(not announced) ["news"] ✗ no match
(NAMESPACE is the response to a subscription; don't confuse it with
PUBLISH_NAMESPACE, which a publisher sends to advertise a namespace.)
A track name has no such structure — it is one opaque byte string, matched exactly. For the full
discovery flow, see
SUBSCRIBE_NAMESPACE and track namespace prefix matching.
Common mistakes
- → Flattening the namespace to a string.
"sports/live/game42"is not the same as the tuple["sports","live","game42"]. The tuple boundaries are what prefix matching keys on; a slash-joined string loses them. - → Putting the track name in the namespace. A
SUBSCRIBEneeds both fields; folding"video"into the namespace tuple means no track name to subscribe to. - → Expecting a track name to prefix-match. Only the namespace does. A "track does not exist" error after a
SUBSCRIBEis usually a name that does not match exactly. - → Sending an empty track name. Drafts 07–22 allow it. In draft-23 the peer closes the session with
PROTOCOL_VIOLATION.
Frequently asked questions
What is the difference between Track Namespace and Track Name in MoQT?
What is a Track Namespace in MoQT?
What is a Track Name in MoQT?
What is the Full Track Name in MoQT?
Is the Track Namespace / Track Name split the same in every MoQT draft?
Related
- The MoQT SUBSCRIBE message, field by field
- SUBSCRIBE_NAMESPACE and track namespace prefix matching
- How MoQT subscriptions work: filters, forwarding, and lifecycle
- MoQT control message type reference (every draft, 07–23)
- MoQT spec — Track Naming (draft-23)
- What is MoQT? — protocol overview
See namespaces and tracks on the wire
moqtap decodes every SUBSCRIBE, SUBSCRIBE_NAMESPACE, and PUBLISH_NAMESPACE — showing the exact namespace tuple and track name your implementation sent, across drafts 07–23.