MIME Types
100 content types mapped to their file extensions, plus the handful of mistakes that actually break things.
text/
Human-readable text. Almost always sent with a charset parameter.
| Extension | Content-Type | Note |
|---|---|---|
.txt | The default for unknown text. Add charset=utf-8 — otherwise legacy clients guess Latin-1. | |
.html · .htm | Browsers only render a response as a page when it is exactly this type. | |
.css | A style sheet with the wrong type is refused by strict browsers. | |
.js · .mjs | RFC 9239 picked this over application/javascript. Modules need it to load. | |
.csv | No standard way to declare the delimiter; most consumers assume a comma. | |
.tsv | ||
.md | Servers often send text/plain instead, which makes the browser show raw source. | |
.xml | application/xml is now preferred; text/xml is legacy but still everywhere. | |
.xhtml | Parsed with a strict XML parser — one unclosed tag blanks the page. | |
.ics | Calendar invites. Doubles as the iCalendar file type. | |
.vcf | Contact cards. | |
.diff · .patch | ||
.srt | SubRip subtitles have no registered type; text/plain is the common choice. | |
.vtt | WebVTT — the format <track> elements expect. |
image/
Raster and vector images.
| Extension | Content-Type | Note |
|---|---|---|
.png | ||
.jpg · .jpeg · .jpe | ||
.gif | Still the only widely supported lossless animation format outside video. | |
.webp | Typically 25–35% smaller than JPEG at similar quality. | |
.avif | AV1-based, usually the smallest of the modern formats — but slower to encode. | |
.svg | Served as an image it cannot run scripts; served as a document it can. Mind the risk. | |
.ico | The old image/x-icon is still sent by plenty of servers. | |
.bmp | ||
.tif · .tiff | Not renderable in most browsers — print and scanning territory. | |
.heic · .heif | What iPhones shoot by default. Safari renders it; Chrome and Firefox do not. | |
.jxl | JPEG XL. Excellent ratios, still thin browser support. | |
.apng | ||
.webm (image) | Rarely used as a still-image type; WebP covers most of the same ground. |
audio/
Audio containers and codecs.
| Extension | Content-Type | Note |
|---|---|---|
.mp3 | ||
.wav | Uncompressed and therefore large. audio/x-wav is the legacy alias. | |
.ogg · .oga | Usually Vorbis or Opus inside — the container does not say which. | |
.opus | Best-in-class for speech and real-time. Fine inside .ogg or .webm. | |
.m4a | AAC inside an MP4 container. There is no official audio/m4a. | |
.aac | ||
.flac | Lossless compression; roughly half the size of WAV. | |
.weba | ||
.aif · .aiff | ||
.mid · .midi | Instructions, not sound — playback needs a synthesiser. | |
.wma | No IANA registration; the x- prefix marks it as de-facto. | |
.amr |
video/
Video containers and codecs.
| Extension | Content-Type | Note |
|---|---|---|
.mp4 · .m4v | The safest choice on the web. H.264 + AAC plays everywhere. | |
.webm | VP8/VP9/AV1 + Vorbis/Opus. The open alternative to MP4. | |
.ogv | ||
.mov | QuickTime. Safari plays it; other browsers depend on the codec inside. | |
.avi | De-facto type, not registered. Poor browser support. | |
.mkv | A container, not a codec — the video inside decides whether a browser can play it. | |
.ts | MPEG transport stream — broadcast and HLS segments. | |
.m3u8 | An HLS playlist, not a video file. Safari plays it directly. | |
.mpd | MPEG-DASH manifest. | |
.flv | Flash-era streaming. Dead in browsers, alive in some ingest pipelines. | |
.3gp |
application/
Binary or structured data — JSON, PDFs, archives, documents, executables. The catch-all tree.
| Extension | Content-Type | Note |
|---|---|---|
.json | Must be exactly this for fetch to parse it as JSON in strict clients. | |
.jsonld | The type structured-data scripts expect. | |
.ndjson | Newline-delimited JSON streams. Not registered, but the convention. | |
.pdf | Makes the browser open its inline viewer rather than download. | |
.zip | ||
.gz | Deprecated alias: application/x-gzip. | |
.tar | ||
.7z | ||
.rar | Officially registered as vnd.rar; x-rar-compressed is the old form. | |
.bz2 | ||
.wasm | Required type for streaming compilation — otherwise instantiation falls back and slows down. | |
.doc | ||
.docx | Long, but spelling it exactly right is what makes Word open it cleanly. | |
.xls | ||
.xlsx | ||
.ppt | ||
.pptx | ||
.odt | ||
.ods | ||
.rtf | ||
.epub | Note the +zip suffix — a structured suffix, not a separate tree. | |
.apk | ||
.dmg | ||
.msi | ||
.exe | Never trust a server-supplied type for executables — verify the hash. | |
.deb | ||
.rpm | ||
.jar | ||
.sql | ||
.yaml · .yml | Registered in 2024; text/yaml and application/x-yaml are still common. | |
.toml | ||
.bin | The “I do not know what this is” type. Browsers download it rather than render. | |
.pem · .crt · .cer | Certificates have no single registered type; browsers treat most as downloads. | |
.p12 · .pfx |
font/
Web fonts. Served over CORS, so a missing Access-Control-Allow-Origin breaks them.
| Extension | Content-Type | Note |
|---|---|---|
.woff2? | ||
.woff | The original web font wrapper. Properly compressed. | |
.woff2 | Brotli-compressed; around 30% smaller than woff. Use it first. | |
.ttf | ||
.otf | ||
.eot | Internet Explorer only. Safe to drop in 2026. |
multipart/
Messages made of several independent parts, such as form uploads.
| Extension | Content-Type | Note |
|---|---|---|
form upload | What a browser sends for a file input. Each part carries its own Content-Type; the boundary lives in the header. | |
form post | The default form encoding — key=value pairs, URL-encoded, joined with &. | |
byte ranges | How several HTTP range responses come back in one body. |
message/
Email and other encapsulated messages.
| Extension | Content-Type | Note |
|---|---|---|
.eml | A raw email with headers and body. Great for archiving and tests. | |
partial |
model/
3D models and scenes.
| Extension | Content-Type | Note |
|---|---|---|
.gltf | Text JSON form. | |
.glb | Single self-contained binary — the practical default for the web. | |
.obj | Registered in 2024; text-based geometry with no material data. | |
.stl | 3D printing. Geometry only — no colour or units. | |
.usdz | What iOS AR Quick Look wants. |
Nothing matches that. Try css, image or woff2.
Mistakes that actually break things
Most wrong MIME types are harmless. These are the ones that stop software from working. Browsers recover from a lot, which is exactly why the bug survives to production — it works locally in Chrome and fails in everything strict.
| Wrong | Correct | Why it matters |
|---|---|---|
text/json | application/json | Strict clients refuse to parse it. fetch().json() will still work, but many frameworks will not. |
application/json; charset=utf-8 | application/json (charset is implicit and ignored) | JSON is always UTF-8 by spec, so the parameter is redundant. Harmless, but some strict parsers warn. |
application/javascript | text/javascript | Superseded by RFC 9239, though every browser still accepts it. |
image/jpg | image/jpeg | There has never been an image/jpg type. It works in browsers by luck, not by spec. |
application/x-zip-compressed | application/zip | An Internet Explorer-era alias still emitted by some Windows stacks. |
How the type is decided
The Content-Type header is authoritative. A file extension is only a hint used when
a server has to guess, which is why a misnamed file can still work and a correctly named one can
still be served as application/octet-stream. If a download starts instead of
rendering, the type was wrong — or the server fell back to the default.
Structured types can carry parameters. The one that matters in practice is
charset: text/html; charset=utf-8 tells the browser how to decode the
bytes before it has a <meta> tag to consult. Getting it wrong produces
mojibake, not an error.
FAQ
Content-Type vs MIME type vs media type — same thing?
Almost. “MIME type” is the historical name, “media type” is the current standard term, and Content-Type is the HTTP header that carries it. They refer to the same type/subtype value.
What is a + suffix, as in application/epub+zip?
A structured syntax suffix. It says “the last part is the underlying format, the first part is the meaning”. Parsers can treat the whole thing as the suffix (a zip file) while still understanding the specific type. +json and +xml are the common ones.
Why do fonts need CORS?
Because they are fetched in CORS mode by specification. If a font is served from another origin without Access-Control-Allow-Origin, the browser silently refuses it and the page falls back to a system font — no console error loud enough to notice.
Is application/octet-stream safe as a default?
It is safe but unhelpful: browsers download it rather than render it, and clients lose the ability to pick a parser. Prefer the real type, and keep X-Content-Type-Options: nosniff on so browsers do not try to out-guess you.