HLS & DASH manifest checker
.m3u8 or .mpd URL to see what it actually declares — the real ladder, codecs, segment durations, audio groups — and what it is missing. The failures that matter here are absences, not syntax errors, so nothing reports them.Why manifests fail silently
A manifest is the most diagnostic artifact in a video pipeline: plain text, public, and a complete declaration of everything a player will do. But the problems are almost never visible by reading one, because they are things that are not there — a missing #EXT-X-INDEPENDENT-SEGMENTS, an AUDIO group referenced by a variant and never defined, a CODECS attribute listing video but not audio, a rung 1.1× the bitrate of the one below it.
None of those are syntax errors. No player reports them. They surface weeks later as “buffering on some devices” or “no sound on Chrome”, which is a much harder thing to debug than a parse failure would have been.
Check the segments too
This reads the manifest, which is one request out of thousands. The headers that matter most — CORS and Cache-Control — have to be right on the segments as well, and it is common for a rewrite rule to cover .m3u8 and miss .ts or .m4s. Take a segment URL from the output above and run it through the cache header checker.
Related
To design a ladder rather than inspect one, the bitrate ladder calculator builds one for any codec and content type with a matching ffmpeg command. For the caching side, the Cache-Control generator has presets for both live playlists and immutable segments. Background reading: the HLS guide, MPEG-DASH, and CMAF across both.
Frequently asked questions
- Why does my HLS stream fail with a CORS error?
- A browser player fetches manifests and segments with XHR or fetch, so every one of those responses needs an Access-Control-Allow-Origin header. Native playback on iOS Safari does not go through the same path and often works without it, which is why this reaches production regularly — it fails only in the browser-based players. Note that covering the manifest is not enough: the segments need the header too, and it is common for one to be configured and the other not.
- What does EXT-X-INDEPENDENT-SEGMENTS do?
- It declares that every media segment can be decoded without reference to any other, which is what allows a player to switch renditions at a segment boundary without visible artefacts. A correctly built ladder already satisfies this, so the tag is usually just missing rather than untrue — and adding it lets players adapt more aggressively. If your segments genuinely are not independent, that is a keyframe alignment problem in the encoder.
- How far apart should the rungs of a bitrate ladder be?
- Between about 1.5× and 2× in bitrate. Closer than roughly 1.25× and a player gains almost nothing by switching, so you pay storage and encoding for a rung that never does useful work. Wider than about 3× and every switch is a visible jump in quality, with connections in between forced down to the lower rung.
- Why must CODECS be declared in a master playlist?
- Media Source Extensions requires a codec string before it will allocate a buffer, so a browser player needs to know what a rendition contains without downloading part of it first. Variants with no CODECS attribute are commonly skipped entirely — the rung exists in the manifest and is never selected. The attribute must also list audio and video together when they are muxed, for example avc1.4d401f,mp4a.40.2.
- How long should a live HLS playlist be cached?
- Shorter than the segment duration. A live media playlist gains a segment every few seconds, so if the edge holds it for longer than that it will serve a playlist missing the newest entries and players will stall at the live edge. Segments themselves are the opposite case — they never change once written, so they should carry a long immutable lifetime.
- What causes uneven segment durations?
- Almost always a keyframe interval that does not divide the segment duration exactly, so the packager cuts at the nearest available keyframe instead of the intended boundary. Beyond breaking the target duration guarantee, uneven segments make a player's bandwidth estimate noisy, which causes it to switch renditions more often than conditions warrant.