Summary
Cloudflare's new provisioned relays (dashboard/API, 2026-07-31) authenticate with the JWT in the URL path — https://draft-16.cloudflare.mediaoverquic.com/<token> — and do not read ?jwt=. moq-cli derives the broadcast path from the connect URL path and carries tokens in ?jwt=. Both sides want the same bytes of the URL, so no form composes:
| Connect URL |
Result |
https://draft-16…/<token> |
connects, connected version=moq-transport-16, then publish_namespace broadcast= (empty) → session terminated, reconnect loop |
https://draft-16…/name?jwt=<token> |
webtransport error: closed: code=3 reason=scope resolution failed (relay never sees the token) |
https://draft-16…/<token>/name |
connects, but the whole path is treated as the request path — still publish_namespace broadcast= (empty) → terminated |
On the draft-14 endpoint the rejection is explicit: PublishNamespaceError { request_id: RequestId(0), error_code: 0, reason_phrase: "done" }.
The subscribe side connects and negotiates cleanly in forms 1 and 3 (moq-transport-16 / moq-transport-14), so this is specifically the publisher's namespace naming. Net effect: the README's "moq-lite works with any moq-transport CDN (ex. Cloudflare)" is currently unreachable for publishing with moq import against Cloudflare's tokened relays.
Environment
moq-cli v0.9.10 (cargo install moq-cli, macOS arm64), 2026-08-13
- Cloudflare provisioned relay (dashboard-created), draft-14 and draft-16 endpoints, publish+subscribe starter token
- Publisher:
ffmpeg … -f mpegts - | moq --client-connect <URL> import ts
Relationship to #2730
This is the next layer of the same onion: after #2730 the IETF path announces unasked, but the announce carries an empty namespace whenever the connect path is consumed by auth — which on Cloudflare is always.
Possible directions
- A
--broadcast <path> option (or MOQ_BROADCAST env) on import/export, independent of the connect path — mirrors how moq-net's library API can already name broadcasts explicitly.
- Or a URL convention that survives token-in-path, e.g. fragment (
https://relay/<token>#name).
- Or, when
?jwt= is present and the scheme is a known token-in-path relay, hoist the token into the dial path and use the remaining path as the broadcast name.
Happy to send a PR for whichever shape maintainers prefer.
(Written by Claude Fable 5)
Summary
Cloudflare's new provisioned relays (dashboard/API, 2026-07-31) authenticate with the JWT in the URL path —
https://draft-16.cloudflare.mediaoverquic.com/<token>— and do not read?jwt=.moq-cliderives the broadcast path from the connect URL path and carries tokens in?jwt=. Both sides want the same bytes of the URL, so no form composes:https://draft-16…/<token>connected version=moq-transport-16, thenpublish_namespace broadcast=(empty) → session terminated, reconnect loophttps://draft-16…/name?jwt=<token>webtransport error: closed: code=3 reason=scope resolution failed(relay never sees the token)https://draft-16…/<token>/namepublish_namespace broadcast=(empty) → terminatedOn the draft-14 endpoint the rejection is explicit:
PublishNamespaceError { request_id: RequestId(0), error_code: 0, reason_phrase: "done" }.The subscribe side connects and negotiates cleanly in forms 1 and 3 (
moq-transport-16/moq-transport-14), so this is specifically the publisher's namespace naming. Net effect: the README's "moq-lite works with any moq-transport CDN (ex. Cloudflare)" is currently unreachable for publishing withmoq importagainst Cloudflare's tokened relays.Environment
moq-cliv0.9.10 (cargo install moq-cli, macOS arm64), 2026-08-13ffmpeg … -f mpegts - | moq --client-connect <URL> import tsRelationship to #2730
This is the next layer of the same onion: after #2730 the IETF path announces unasked, but the announce carries an empty namespace whenever the connect path is consumed by auth — which on Cloudflare is always.
Possible directions
--broadcast <path>option (orMOQ_BROADCASTenv) onimport/export, independent of the connect path — mirrors howmoq-net's library API can already name broadcasts explicitly.https://relay/<token>#name).?jwt=is present and the scheme is a known token-in-path relay, hoist the token into the dial path and use the remaining path as the broadcast name.Happy to send a PR for whichever shape maintainers prefer.
(Written by Claude Fable 5)