MoQ News #2: Draft-20 Ships, Joining FETCH Is Gone, and Interop Is Two Revisions Behind
By moqtap team
MoQ News #2
Three weeks since the first issue, and the shape of this one changed twice while we were writing it.
The plan was to report an interim meeting and a pull request queue that was slowly draining. Instead the queue emptied. Between 31 August and 1 September, thirty-two pull requests merged into draft-ietf-moq-transport, draft-20 was published, and the editors went straight into a face-to-face meeting to restructure the document. Thirty-four merged in the entire eight weeks between draft-19 and 30 August; thirty-two landed in the twenty-eight hours that followed.
That is the lede. The counterweight is in the second half of this issue: the interop event running today targets draft-18, and exactly one registered implementation advertises draft-20.
Draft-20 shipped
draft-ietf-moq-transport-20 was published on 31 August 2026, 158 pages, roughly eight weeks after draft-19.
If you have been tracking this from our draft-19 walkthrough, the headline change is that Joining FETCH is gone.
Fill fetch replaces it (#1673, merged 31 August). The old model gave FETCH two variants — “standalone” and “joining” — where a joining fetch was a distinct message shape bolted to an existing subscription. The new model deletes the variant. A subscriber attaches a FILL_PARAMETERS parameter to an ordinary subscription; its presence requests the fill, and it carries a nested sequence of parameters (#1868). The “standalone” moniker goes with it, because there is no longer anything for it to be standalone from.
This is the same consolidation we traced in Three Meetings to Change a Filter — the London interim killed Joining FETCH in principle back in June, and draft-20 is where the deletion actually lands. One message shape fewer, one parameter more.
The rest of draft-20, grouped as the editors grouped it in the release notes:
Session and control plane
- The Location Filter is restructured to match the other filter parameters, and FETCH ranges now travel in
LOCATION_FILTERinstead of message fields (#1809) — the merge our filters post covered. - New
PUBLISH_STATE_NOTIFYmessage (#1820) and newINCLUDE_PROPERTIESparameter (#1813, #1847). PUBLISHcan carry Subscription Parameters, andAUTHORIZATION TOKENis never copied fromSUBSCRIBE_TRACKS(#1834).- Subscription parameters move to
REQUEST_UPDATErather thanPUBLISH_OK(#1790);FORWARDis allowed on aREQUEST_UPDATEforSUBSCRIBE_TRACKS(#1812). - Three removals: the
SUBSCRIPTION_ENDEDreason forPUBLISH_DONE(#1833) — a subscription no longer ends merely because Largest Object passes the end of the Location Filter; the requirement that a publisher retain Largest Location (#1872); and theVERSION_NEGOTIATION_FAILEDsession error (#1867). - A relay MUST send an upstream FETCH to at least one publisher (#1804), and the draft now discusses the tradeoffs of aggregating downstream filters onto one upstream subscription (#1735) — the relay behaviour we described in How MoQT Relays Work getting its explicit treatment in the text.
Data plane
OBJECT_DATAGRAMandSUBGROUP_HEADERtypes are now described as Type Flags bitfields, and setting a bit with no specified meaning is aPROTOCOL_VIOLATION(#1774). If you wrote a parser against draft-19’s enumerated types, read this one first.OBJECT_DELIVERY_TIMEOUTnow starts at the last header byte instead of the first payload byte (#1844) — a small change with a real effect on anyone measuring against the timeouts we covered in delivery order and priority.- New
End of Timed-Out Rangemarker for objects abandoned when the Fill Timeout expires (#1822), and defined scheduling between fill-delivered and subscription-delivered objects (#1673). - A warning about re-using a Track Alias across concurrent subscriptions (#1856).
Security. A new Preventing Impersonation section (issue #1737, #1789), expanded mutual TLS and authorization guidance (#1786), moqt URI scheme considerations (#1772), and — notably — a recommendation of end-to-end object encryption for confidentiality from relays (#1755). That last one is the transport draft formally pointing at Secure Objects as the answer to “the relay can read my media.”
The above is the editors’ own changelog, and on two counts it undersells the revision. We diffed the published
-19and-20documents afterwards and wrote the result up separately in MoQT Draft-20: What Changed Since Draft-19. The short version: the FETCH message was rewritten, not trimmed —Fetch Typeis gone and Track Namespace and Track Name are now inline, at the same message type0x16, so a draft-19 parser misreads a draft-20 FETCH silently. And the provisional Property registry entry filed under “Notable Editorial Changes” is a codepoint reassignment across two specifications:VIDEO_FRAME_MARKINGmoved0x0A→0x09and0x0Anow belongs to Secure Objects’ENCRYPTED_LIST. If you implement against draft-20, read that post rather than this section.
What -21 and -22 are for
Ian Swett set the schedule out on the list the same day:
The authors and editors of MoQT are working on some larger editorial changes, so we just shipped a -20 prior to making those changes. Once the edits are made, we’ll ship a -21, so the diff between -20 and -21 will be purely editorial. We plan to ship a -22 around Sept 15th, 4 weeks before the Seattle interim.
That work started immediately. On 1 September, sixteen pull requests merged in a single day, led by “Draft Restructuring Phase I: move-only edits” — error codes consolidated into one Error Handling section, Track Namespace and Authorization Token Compression extracted into common sections, wire formats moved next to the parameters they encode, stale sections deleted, and the term “subscription” finally given a definition (#1884).
One of those is not purely cosmetic for implementers: “Forwarding Preference” is renamed to “Delivery Mode” (#1886), with leftover mentions swept up in #1891. The concept is unchanged; every piece of documentation, tooling, and log output that says “forwarding preference” is now using the old name.
A correction to our own coverage. After the 10 August interim we reported — from the minutes, which say it in as many words — that draft-20 “will consist of purely editorial changes.” That is not what shipped, and it appears to be a garbled transcription rather than a change of plan: it is the -20 to -21 diff that is meant to be purely editorial, which is exactly what Ian Swett describes above. Draft-20 carried the entire accumulated normative queue since draft-19. Our filters post and the update notes on News #1 and the IETF 126 recap said draft-22 would be the next interop target, and that part holds — it now has a date, around 15 September.
The 24 August interim
The working group met virtually on 24 August. Minutes were posted on 31 August; Ian Swett drove the session from a PRs and issues deck.
A note on the numbers. Two of the identifiers in the published minutes do not match the repository. The minutes attribute the location filter and fill fetch discussion to “PRs 1823 & 1824” — both of which are unrelated pull requests that merged on 30 July — and label the “or” filter debate “Issue 1881”, which is an editorial pull request from 1 September. Matched on content, the discussions were about the location filter and fill fetch work that landed as #1809 and #1673, and about issue #1801, “Reconsider ‘OR’ functionality in range filters” — which was closed at 17:58 UTC that afternoon, shortly after the session. We flag this because chasing the printed numbers will send you to the wrong documents.
Joining fetch is still confusing, and that is now an editorial action item. Cullen Jennings raised that configuring a standard joining fetch is hard to understand under the proposed filter text. Martin Duke acknowledged that although relative (group-only) and absolute (group and object) filters are compact, the layout is unintuitive. Mo Zanaty clarified the actual recipe — for the common case, a subscriber sets an ordinary location filter and appends an empty fill-fetch parameter — and he and Ian Swett took an action item to write a dedicated subsection spelling it out step by step. Worth noting: the ergonomics complaint arrived before the change shipped, and the answer was documentation rather than redesign.
“Or” filters survive a removal attempt. Range filters are optional and location filters do not carry Set IDs, but other filters can use Set IDs to express “or” queries — which is also what lets a relay deduplicate identical upstream requests. Victor Vasiliev questioned whether the complexity was justified by the use cases and suggested removing it now and reintroducing it if real demand appeared. Mo Zanaty and Luke Curley defended it on property filtering and upstream aggregation grounds; Cullen Jennings added that deduplication is trivial to implement and that removing “or” now would make it considerably harder to specify later. Ian Swett raised the cost of updating individual filter sets, and Mo Zanaty clarified that any update replaces the entire filter parameter rather than patching individual Set IDs. Consensus: keep it. Issue 1801 closed the same afternoon.
Namespace subscriptions get parameters (issue #1800). Luke Curley proposed adding parameters to SUBSCRIBE_NAMESPACE to match PUBLISH_NAMESPACE — for signalling ETags, start times, or custom hop weights to help multi-connection routing. Martin Duke cautioned that allowing REQUEST_UPDATE on namespace subscriptions brings significant state-machine complexity, and proposed unilateral notification instead. The group agreed to add the parameters with updates restricted to a unilateral signalling model, no REQUEST_UPDATE.
Immutable means immutable (issue #1703). On what a relay should do with conflicting values for immutable object fields: nothing clever. Because objects and their properties are structurally immutable, the protocol will not define a cache-update mechanism; a relay that receives a conflicting value ignores the later one, preserving eventual consistency.
Nonexistent objects stay nonexistent. Cullen Jennings raised the case where an endpoint is told an object does not exist and then receives it anyway. The group agreed the transition is invalid — and, importantly, that it will be classified as a malformed track error rather than a generic protocol error, so it does not tear down the upstream connection. That distinction is the difference between one bad track and a dropped session for every subscriber behind the relay.
Top Tracks gets cheaper (#1830). Mo Zanaty plans to rework the Top Tracks filter to use the newly merged PUBLISH_STATE_NOTIFY mechanism, which he expects to halve control channel traffic during track switches by removing the REQUEST_UPDATE and OK round trip. The PR is still open; its last update was 27 August.
The priority feature that would not die
The most instructive thread of the fortnight is about a change that was agreed to be dropped and then was not.
PR #1770 makes DEFAULT_PUBLISHER_PRIORITY an updatable parameter rather than a fixed initial value. We covered the design in News #1. After the 10 August interim, Martin Duke opened a call for comments on the list noting that nobody on the call would assert the compression was critical, but that proponents may have been absent. The chair slides at the 24 August interim recorded the outcome: the call ends today, and the consensus is to close the PR with no action unless new feedback arrives on the mailing list.
New feedback arrived on the mailing list.
Cullen Jennings replied the same day that the question conflated two separate things — allowing publisher priority to change, and making that change race-free and object-perfect — and that the use cases for the first are clear. Alan Frindell then made the sharpest correction: the proposal saves at most one byte per datagram or subgroup, not the two or three the interim had been arguing about, and everyone who had expressed interest had already made clear that perfect fidelity was not a requirement. He floated a SETUP option letting the receiver opt in, or moving the machinery to an extension document — but added that the core of 1770, moving Default Publisher Priority back from a property to a parameter and relaxing the malformed-track rules around priority, needs to happen in the base draft regardless.
Victor Vasiliev remains the clearest opponent, and his argument is worth reading in full:
I think people underestimate the potential downsides of parties not having a consistent view of publisher priority. Things will work most of the time, but once in a while, active speaker detection will break for some users, and it will be a giant pain to debug.
Suhas Nandakumar came down in favour and asked whether PUBLISH_STATE_NOTIFY — brand new in draft-20 — could carry the change. Alan Frindell’s answer is a nice piece of protocol reasoning: REQUEST_UPDATE is better here precisely because it is a request, since the arriving REQUEST_OK tells the publisher when it is unequivocally safe to stop sending explicit priority and resume compressing.
The PR is still open as of today. Two things make this worth watching beyond its own merits. First, it is a working example of the mailing list doing what the “unless new feedback is received” escape hatch is for — a call for comments that actually reversed a room’s consensus. Second, the debugging argument cuts both ways for anyone building tooling: a priority value that is correct on the wire but inconsistent between endpoints is exactly the class of bug that only a trace of both sides will explain.
Interop: the event is today, and it targets draft-18
Mike English announced on 21 August that the virtual interop hackathon would run today, Wednesday 2 September, all day, with the primary focus on draft-ietf-moq-transport-18. This is the event we have been unable to date since Vienna; it was never registered as a datatracker interim, which is why it never appeared on the meeting calendar.
The gap is the story. The specification is at -20. The interop target is -18. The interop runner registry confirms it: current_target is draft-18, and of 23 registered implementation entries, fifteen advertise draft-18, one advertises draft-19, and exactly one advertises draft-20 — moq-go, which added the moqt-20 ALPN on 1 September, the day after the draft shipped. One entry is still on draft-13.
This is not a criticism of anyone. It is the arithmetic of a specification that moved 158 pages’ worth in a week, and it is precisely why the editors are cutting -22 four weeks before Seattle rather than the week of it.
Two details from the registry are worth having if you are testing this week:
- ALPN negotiation is a live failure mode. The registry itself records that
moxygen’s pre-built interop client was missingmoqt-18from its ALPN list at build time, so it cannot negotiate against draft-18-only relays, with a fix tracked upstream — and it flags thatmoqx, which is built on moxygen, may have inherited the same gap. If your draft-18 test fails before any MoQT message is exchanged, check the ALPN list before you check your parser. - Cloudflare has a draft-18 endpoint now.
draft-18-interop.cloudflare.mediaoverquic.comjoins the long-standingdraft-14one, on both raw QUIC and WebTransport.
Mike English also asked participants to record the things the automated matrix cannot capture — application-level flows, draft ambiguities, how tests were set up — in the ad hoc interop reports wiki. That is the more valuable artifact of the two, and historically the emptier one.
One public commitment came back on the thread: Steven Riedl of Pluto TV offered a relay endpoint running moq-relay and accepting drafts 14 through 19, carrying two live server-side ad-insertion channels around the clock, plus client tooling. Their stitcher-moq entry landed in the runner on 1 September with the broadest draft coverage in the registry — 14 through 19. A continuously running relay with real live media and mid-stream joiners exercises different code paths than short test clips, and there are not many of those in the registry.
New drafts
The pile is now at 45 active drafts carrying “moq” in the name, against 44 in the last issue. Adopted documents remain at seven, with transport at -20 and the other six unchanged.
draft-yuyou-moq-conditional-filtering-00 (27 August, announced 18 August). Yu You of Nokia proposes binding conditional evaluation logic directly to Range Filter sets. The argument: subscription filters are static once established and can only change through explicit subscriber signalling, so a relay adapting to real-time network conditions must wait a round trip. Conditional filters let the relay adapt intra-track forwarding autonomously.
Read this next to the “or” filter debate above and a theme appears. The working group spent 24 August arguing about whether Set IDs were too much filter machinery to keep; a week later a new draft proposes attaching conditional logic to those same sets. Filters keep accreting expressiveness, and the pushback keeps being about relay complexity. Nokia’s moqt-nr relay is in the interop registry at draft-18, so this is coming from someone running one.
draft-jennings-moq-discovery-00 (14 August). Cullen Jennings defines how MOQT clients discover server endpoints via DNS and mDNS — SVCB and HTTPS record mappings for the moqt URI scheme, SRV records as a fallback, and DNS-SD over mDNS for local network discovery. This fills a real hole: draft-20 spends genuine effort on moqt URI semantics, including defining host resolution and excluding the query component from scope, but says nothing about how you find a relay in the first place. The mDNS half is the more interesting one, because local discovery is a conferencing and device-to-device story rather than a CDN one.
draft-defoy-moq-relay-network-handling-05 (20 August). A revision of the relay network-handling draft.
Still absent: the management, metrics, and diagnostics document the working group agreed in Vienna to spin out of transport, with Alperen Temel, Alan Frindell, and Ian Swett attached. No -00 yet, three weeks after we last checked. It remains the most consequential missing document for anyone building observability on MoQT.
Dates ahead
| When | What |
|---|---|
| 2 September (today) | Virtual interop hackathon, targeting draft-18 |
| 8 September | Virtual interim (interim-2026-moq-23) |
| ~15 September | draft-21 (editorial) and draft-22 — the Seattle interop target |
| 21 September | Virtual interim (interim-2026-moq-24) |
| 14–15 October, Seattle | In-person interim, four live sessions across two days |
| 14 November, San Francisco | IETF 127 |
The Seattle dates are as registered on the datatracker: two sessions on the 14th and three on the 15th, one of which still carries the note “Canceling to reschedule with updated timezone” and should not be planned around. The interop announcement referred to the interim as “October 12–15”, which we cannot reconcile against those registrations; if you are booking travel, confirm before you commit to the wider window.
Next issue in two weeks — by which point draft-22 should exist and today’s interop results should be published.