Sign in

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 SUBSCRIBE needs 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 SUBSCRIBE is 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?
The Track Namespace is an ordered tuple of byte-string components that groups related tracks (for example ["chat", "room1"]). The Track Name is a single byte string that identifies one track inside that namespace (for example "messages"). The namespace is the folder; the name is the file. Together they form the Full Track Name, which uniquely identifies a track. The namespace supports prefix matching for discovery; the name is always matched exactly.
What is a Track Namespace in MoQT?
A Track Namespace is an ordered tuple of byte-string components — like ["sports", "live", "game42"] — used to group related tracks and to discover them. It has at most 32 components: at least one in drafts 07–16, and possibly none from draft-17. Because it is a tuple, a subscriber can register interest in a prefix such as ["sports"] via SUBSCRIBE_NAMESPACE and receive announcements for every namespace that begins with it.
What is a Track Name in MoQT?
A Track Name is a byte string that names one specific track within a Track Namespace — for example "video", "audio", or "messages". It is carried in SUBSCRIBE, FETCH, and PUBLISH alongside the namespace, and it is always matched exactly (unlike the namespace, which supports prefix matching). In drafts 07–22 a Track Name may be empty. In draft-23 it must be at least one byte long, and an endpoint that receives an empty one closes the session with PROTOCOL_VIOLATION.
What is the Full Track Name in MoQT?
The Full Track Name is the pair (Track Namespace, Track Name) taken together. It is the globally unique identifier for a track. On the wire, subgroup streams and datagrams reference a track by a compact integer Track Alias instead of repeating the full namespace and name on every object.
Is the Track Namespace / Track Name split the same in every MoQT draft?
Yes, in drafts 07–23 of draft-ietf-moq-transport: the namespace is a tuple of at most 32 components, the name is a byte string, and the two combine into the Full Track Name. Two limits differ by draft. A namespace has at least one component in drafts 07–16 and may have none from draft-17. A Track Name may be empty in drafts 07–22 and must not be in draft-23. The messages that carry them differ more: see the table of which message uses which field.

Related

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.