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–19 (current: draft-19).
Side by side
| Track Namespace | Track Name | |
|---|---|---|
| What it is | An ordered tuple of 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 / 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 data streams that follow reference the track by its alias. (Exactly where the alias is assigned has shifted across drafts — see the message-type reference for the byte-level layout in a specific draft.)
Where each one appears
The distinction is easiest to see by which control messages use which field:
| Message | Track Namespace | Track Name | Role |
|---|---|---|---|
| SUBSCRIBE | Full tuple | Exact name | Identifies the one track to receive objects from |
| FETCH | Full tuple | Exact name | Identifies the track to pull historical objects from |
| PUBLISH | Full tuple | Exact name | Announces a specific track a publisher will serve |
| SUBSCRIBE_NAMESPACE | Prefix tuple | — (not used) | Registers interest in a namespace prefix; no track name |
| PUBLISH_NAMESPACE | Full tuple | — (not used) | A publisher advertises that it has tracks in a namespace |
| NAMESPACE | Suffix tuple | — (not used) | The relay’s response to SUBSCRIBE_NAMESPACE — carries the namespace suffix after your prefix (draft-17+) |
Note the last two rows: namespace-discovery messages use only the namespace (as a prefix), 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 (draft-17+):
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.
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?
Does the Track Namespace / Track Name split change between MoQT draft versions?
Related
- The MoQT SUBSCRIBE message, field by field
- SUBSCRIBE_NAMESPACE and track namespace prefix matching
- How MoQT subscriptions work: filters, forwarding, and lifecycle
- MoQT message-type reference (field-level detail)
- MoQT spec — Representing Namespace and Track Names (draft-19)
- 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–19.