Serving HLS out of Cloudflare R2.
HLS is a manifest plus segments. Once those files exist in a bucket behind a domain, R2 is a competent origin. This page describes the layout, the headers that matter, and where setups usually break.
Short answer
R2 serves HLS fine; producing the HLS is the work.
An HLS stream is a text manifest (.m3u8) that lists media segments (.ts or .m4s) plus per-rendition child manifests. All of them are ordinary objects. R2 serves them over HTTPS with $0 egress, and a player will do adaptive switching against them without R2 knowing anything about video.
The real requirements are correct content types, a stable path layout, and CORS if the player is on a different origin than the bucket domain.
Estimate this workload in the calculator See how BYO storage works
Getting it right
Three things that decide whether playback works.
Almost every broken R2 HLS setup fails on one of these rather than on R2 itself.
Content types
The manifest must be served as application/vnd.apple.mpegurl and segments as video/mp2t or video/iso.segment. A generic octet-stream will make some players refuse the stream.
Relative paths
Keep segment references relative to the manifest. Absolute URLs bake in a hostname and break the moment you move the domain or sign the URLs.
CORS
If the page and the bucket domain differ, the bucket needs CORS rules allowing GET from the playback origin, or the player fails silently on the manifest fetch.
Layout
A rendition ladder as it sits in the bucket.
| Object | Purpose | Typical size (10-min source) |
|---|---|---|
| master.m3u8 | Lists available renditions | under 1 KB |
| 1080p/index.m3u8 | Segment list for 1080p | a few KB |
| 1080p/seg-*.ts | 1080p media segments | around 750 MB |
| 720p/seg-*.ts | 720p media segments | around 350 MB |
| 480p/seg-*.ts | 480p media segments | around 150 MB |
| source.mp4 | Retained master | varies with capture |
Sizes assume roughly 1.5 GB per hour at 1080p and a standard three-rung ladder. Storing renditions alongside the master is why a video library bills for more GB than the raw footage suggests.
Common questions
HLS-on-R2 questions.
Does R2 need special configuration for HLS?
No R2-specific feature is required. What matters is object content types, a custom domain and CORS. R2 treats the files as ordinary objects.
Can I use signed URLs with HLS?
Yes, but every segment request needs to be authorised, not just the manifest. That usually means signing at an edge layer rather than pre-signing each object by hand.
Is DASH supported too?
Yes, the same way. DASH is an MPD manifest plus segments, and R2 serves them identically.
Where does transcoding happen?
Outside R2. Either you run FFmpeg yourself or a service produces the ladder and writes it into the bucket. NULX does the latter.
Sources
Rates checked September 10, 2026 · Page updated September 10, 2026
Next step
Skip the pipeline build.
NULX produces the HLS ladder and writes it into your own R2 bucket, so you keep the files and skip the encoding infrastructure.