M3U test playlist: how to check an IPTV playlist works
An M3U playlist "works" when it parses as valid extended M3U, every entry has the metadata your player needs to display it, and every stream URL behind it actually loads. Checking a playlist means testing all three separately, because a playlist can pass the first two and still fail on dead links.
Most IPTV playlist problems are not exotic: a missing #EXTM3U header, a stream URL with an expired token, or a group-title that does not match what the app expects. A playlist checker walks the file line by line and flags which of these it is, rather than leaving you to guess from a generic "channel not available" message in the player.
This guide covers what a checker actually verifies in an M3U/M3U8 playlist, the attributes that most often break in real players, and how to read the difference between a syntax problem in the file and a delivery problem with the streams themselves.
What makes a file valid extended M3U in the first place
A valid extended M3U playlist starts with a first line of exactly #EXTM3U, with no leading blank line and no byte-order-mark before it in most parsers (some tolerate a UTF-8 BOM, others reject the file outright). After that, entries alternate: a #EXTINF line describing the next stream, followed by a line with the stream URL. A playlist with a URL line that has no preceding #EXTINF still plays in permissive players like VLC, but IPTV apps that build a channel list from the EXTINF metadata will either skip the entry or show it with a blank name.
Line endings matter more than people expect. A playlist saved with bare CR (old Mac-style) instead of LF or CRLF breaks parsers that split only on \n, producing one giant line that fails silently. Checkers normalize line endings first and report if the raw file used something other than LF or CRLF.
What has to be right in every #EXTINF line
The #EXTINF line format is #EXTINF:duration attribute="value" ...,Display Name. For live IPTV the duration is conventionally -1 since the stream has no fixed length; a positive duration on a live entry is not a parse error but signals the entry was authored for VOD tooling and some IPTV apps will treat it as time-limited content and refuse to loop it.
The three attributes that IPTV apps actually key on are tvg-id (used to match the channel to an EPG entry), tvg-name (a human display name, sometimes reused as the EPG match key when tvg-id is absent), and group-title (which category or bouquet the channel is sorted into in the app UI). A channel with no group-title usually lands in an "Uncategorized" or "Undefined" bucket rather than being hidden, so a missing group-title is a UX problem, not a fatal one.
tvg-logo is optional but its absence is the single most common reason a channel shows a blank tile: most players do not fall back to a generic icon, they just render nothing. If tvg-logo is present, the checker should confirm the URL responds with an image content-type and not a 404 or an HTML error page, since a broken logo URL looks identical to a missing one in most UIs.
Catch-up and player-specific tags: #EXTVLCOPT and friends
#EXTVLCOPT lines carry VLC-specific playback options, most commonly #EXTVLCOPT:http-user-agent= to spoof a user agent the origin server requires, and #EXTVLCOPT:http-referrer= for streams that check a Referer header. These lines are VLC-only by convention; other players either ignore them entirely or, for Tivimate-style apps, expect the equivalent information passed as URL-appended headers (using a |-separated syntax such as stream.m3u8|User-Agent=... ) instead. A playlist authored with only #EXTVLCOPT lines can play perfectly in VLC and fail with a 403 in every other player, which is a common source of "it works for me" bug reports.
kodiprop and catchup-related tags (catchup="append", catchup-days="7") are read only by Kodi-family players (Kodi, TiviMate). A checker that does not understand a given tag should report it as an unrecognized-but-harmless extension rather than a syntax error, since ignoring unknown attributes is the correct and expected parser behavior for extended M3U.
Does the stream URL itself actually load
Syntax validity and playability are independent checks. A URL can be syntactically fine and still fail because of an expired token, a geo-block returning 403, or a certificate error on an https endpoint. Checking playability means issuing a request to the URL and confirming the response is a stream manifest (an HLS #EXTM3U playlist, or a DASH MPD starting with an XML declaration and an <MPD> root) rather than an HTML login page or an error body, which some IPTV providers return with a 200 status specifically to defeat simple up/down monitors.
For HLS entries, resolving one level further into the referenced media playlist (or the first variant if the URL is a master playlist) catches a class of failure where the master manifest loads but every listed variant is dead — a broken-CDN pattern common on resold IPTV lines.
Encoding and character problems that corrupt channel names
M3U files must be UTF-8. A playlist authored in Windows-1252 or another single-byte encoding renders accented channel names (e.g. "Deutschland") as mojibake in players that assume UTF-8 without sniffing, even though the file "works" in a text editor that auto-detects encoding. A checker should flag any byte sequence that is not valid UTF-8 rather than only checking that the visible text looks plausible.
Commas inside a display name that are not escaped will truncate the name at the first comma, because the format specification treats the first comma after the duration as the separator between attributes and the display name. A channel named "News, Live" with no escaping shows up as just the text before the comma in strict parsers.
Duplicate and conflicting entries
Two entries with the same tvg-id are not a syntax error, but they break EPG matching: the app has to arbitrarily pick which one gets the guide data, and it is usually the last one parsed. Duplicate stream URLs under different channel names are legitimate (a provider mirroring the same feed under two brand names) but duplicate tvg-id with two different URLs is almost always a copy-paste mistake in the playlist and worth flagging even though it will not crash anything.
Step by step
- Confirm the file starts with #EXTM3U on the first line with no BOM or leading blank line.
- Parse every #EXTINF/URL pair and flag any URL line with no preceding #EXTINF.
- Check that tvg-id values are present and unique across the file.
- Fetch each tvg-logo URL and confirm it returns an image, not a 404 or redirect to a login page.
- Request each stream URL and confirm the response is a real HLS or DASH manifest, not an HTML error page.
- For HLS entries, resolve one variant deep to catch master-playlist-loads-but-all-variants-dead failures.
- Re-check the file is valid UTF-8 and that no display name contains an unescaped comma.
Run it yourself
Free, no sign-up, and every finding links to an explainer.
Frequently asked questions
- Does a playlist need tvg-id on every channel to work?
- No — the playlist will still load and play without tvg-id. What breaks is EPG matching: without tvg-id (or a tvg-name the guide provider also recognizes), the app has no reliable key to attach programme data to that channel, so it shows the channel with no guide information.
- Why does my playlist play in VLC but not in my IPTV app?
- The most common cause is #EXTVLCOPT lines carrying headers (user agent, referrer) that only VLC reads. Other players need the equivalent header information appended to the URL in their own syntax, or they need the header set globally in the app rather than per-channel.
- Is a positive duration on a live channel wrong?
- It is not a parsing error, but it is unconventional. Live entries are normally written with a duration of -1; a positive number suggests the entry was generated by VOD-oriented tooling and some players may apply time-limited playback logic that does not suit a 24/7 live feed.
- Can a playlist look fine in a text editor but still be broken?
- Yes. Wrong-encoding files display correctly in editors that auto-detect encoding but render as mojibake in players that assume UTF-8. Line endings using bare CR also look normal in most editors but can make a strict M3U parser treat the whole file as one unparseable line.
- Should I remove channels with dead stream URLs from the playlist?
- That depends on whether the outage is temporary. A checker that reports "URL unreachable" once is not proof the channel is permanently gone — recheck at a different time before deleting the entry, since many IPTV sources have scheduled maintenance windows or short-lived CDN blips.
IPTV playlists findings, explained
Read next
Last reviewed 2026-09-16.