M3U8 MIME Type – Free, Online, Private
application/vnd.apple.mpegurl is the type for an HLS playlist. The file is UTF-8 text, not the media segments.
What .m3u8 is
An .m3u8 file is an HTTP Live Streaming playlist. It is text. It starts with #EXTM3U. Tags such as #EXT-X-VERSION, #EXT-X-TARGETDURATION, and #EXTINF describe the segments that follow as URLs. A master playlist lists variant streams. A media playlist lists files, which are often MPEG-TS segments with the type video/mp2t or fragmented MP4 with video/mp4. The playlist itself is application/vnd.apple.mpegurl. application/x-mpegURL is the older unofficial value. The file is UTF-8. Sending a charset is reasonable because the body is text and a default of a legacy encoding will corrupt non-ASCII titles and URLs.
IANA registers application/vnd.apple.mpegurl. The media type is application/vnd.apple.mpegurl. Extensions that use it on this page: .m3u8. A client compares the type, not the filename, once the response has arrived. The filename still matters on disk and in Content-Disposition, which is why a wrong extension and a wrong header are two different bugs.
What sends application/vnd.apple.mpegurl
What sends application/vnd.apple.mpegurl: Send application/vnd.apple.mpegurl; charset=utf-8 on the playlist response. Do not send that type on the segments. A player that receives a transport stream where it expected a playlist fails immediately, and the reverse failure is a playlist parsed as video. Cache a media playlist for about one target duration if it is a live window, and cache a master playlist only as long as the variant set stays stable. A VOD playlist can be cached longer. The type does not change between live and VOD. The tags do. The file on disk is still .m3u8. Once the response exists, a client trusts application/vnd.apple.mpegurl, not the filename. Sign segment URLs if the media is private, and keep the playlist on a short lifetime so the signatures can rotate. The Content-Type stays application/vnd.apple.mpegurl on every refresh. Changing the type between refreshes is a good way to make a native player stick on the first error.
Content-Type for .m3u8
Send application/vnd.apple.mpegurl; charset=utf-8. The charset parameter names the encoding of the body. Leaving it off forces the client to guess, and for several text types the registered default is not UTF-8. Do not send a charset on a redirect. The header belongs on the response that contains the bytes.
Content-TypeContent-Type: application/vnd.apple.mpegurl; charset=utf-8
nginx, Apache, and Express
These snippets map .m3u8 to application/vnd.apple.mpegurl. nginx reads the types block when it picks a type from the URL's extension. A location that sets default_type, or an application that sets the header itself, overrides that map. Apache AddType applies in the directory context where you put it. The Express static example writes the header for files ending in .m3u8 so a stale mime database in the framework cannot disagree with the type on this page.
nginx# /etc/nginx/mime.types, inside the types { } block
application/vnd.apple.mpegurl m3u8;
charset utf-8;
charset_types application/vnd.apple.mpegurl;
ApacheAddType application/vnd.apple.mpegurl .m3u8
AddCharset UTF-8 .m3u8
Expressimport express from "express";
const app = express();
app.use(express.static("public", {
setHeaders(res, filePath) {
if (filePath.endsWith(".m3u8")) {
res.setHeader("Content-Type", "application/vnd.apple.mpegurl; charset=utf-8");
}
},
}));
Pitfalls for application/vnd.apple.mpegurl
Pitfalls that show up for application/vnd.apple.mpegurl, and not for a neighboring type with a similar extension: The expensive bug is a CDN that serves the playlist as text/plain or application/octet-stream. Native players on Apple platforms are strict about the type. Another bug is a playlist saved as UTF-16 by an editor. The #EXTM3U magic then has zero bytes between the letters and the player rejects it. Write UTF-8. A third is an EXT-X-KEY URI that points at a key served with the playlist type. The key is binary and needs its own type, often application/octet-stream. A fourth is mixing .ts and .m4s segments in one playlist without the tags that say so.
- application/vnd.apple.mpegurl and audio/mpegurl are different registrations. A video HLS playlist uses the Apple vendor type.
- The playlist must use LF or CRLF consistently enough for the player. A JSON API that escapes the body onto one line is no longer a playlist.
- Gzip is appropriate. It is text. Set Content-Encoding and leave the type alone.
- A master playlist does not include #EXTINF segment durations. Do not serve it where a media playlist was expected.
Frequently asked questions
What type does HLS require?
application/vnd.apple.mpegurl for the playlist. Segments are a different type, usually video/mp2t or video/mp4.
Is application/x-mpegURL still used?
Old servers send it. The registered type is application/vnd.apple.mpegurl. Prefer that.
What is the first line?
#EXTM3U. If you do not see that, the file is not a playlist.
Should the playlist be cached like the video?
A live media playlist should expire quickly. The segments can live longer. The type is the same either way.