MIME Types (Content-Type) Reference
File extensions mapped to their correct MIME types — documents, images, audio, video, fonts, archives and code — with a live filter and the Content-Type mistakes that actually break things.
A MIME type (media type) tells the receiver what a byte stream is so it can be parsed, rendered or executed correctly. On the web it travels in the Content-Type header, and getting it wrong has real consequences: browsers refuse to run module scripts served as text/plain, ignore stylesheets with the wrong type, won't render fonts, and APIs reject request bodies they can't identify. This table lists the correct type for the extensions you'll actually serve.
Text & documents
| Extension | MIME type | Notes |
|---|---|---|
| .html .htm | text/html | Serve with charset=utf-8 |
| .css | text/css | Browsers ignore stylesheets with any other type in strict mode |
| .txt | text/plain | |
| .md | text/markdown | RFC 7763; many servers still send text/plain |
| .csv | text/csv | RFC 4180 |
| application/pdf | ||
| .rtf | application/rtf | |
| .doc | application/msword | Legacy Word 97–2003 |
| .docx | application/vnd.openxmlformats-officedocument.wordprocessingml.document | Modern Word |
| .xls | application/vnd.ms-excel | Legacy Excel |
| .xlsx | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet | Modern Excel |
| .ppt | application/vnd.ms-powerpoint | Legacy PowerPoint |
| .pptx | application/vnd.openxmlformats-officedocument.presentationml.presentation | Modern PowerPoint |
| .odt | application/vnd.oasis.opendocument.text | OpenDocument text |
| .ods | application/vnd.oasis.opendocument.spreadsheet | OpenDocument spreadsheet |
| .odp | application/vnd.oasis.opendocument.presentation | OpenDocument presentation |
| .epub | application/epub+zip | |
| .ics | text/calendar | iCalendar events |
| .vcf | text/vcard | Contact cards |
| .xml | application/xml | RFC 7303; text/xml is an accepted alias |
| .xhtml | application/xhtml+xml |
Images
| Extension | MIME type | Notes |
|---|---|---|
| .png | image/png | |
| .jpg .jpeg | image/jpeg | Always jpeg in the type, even for .jpg |
| .gif | image/gif | |
| .webp | image/webp | |
| .avif | image/avif | |
| .svg | image/svg+xml | Wrong type = broken <img>; can carry scripts, mind your CSP |
| .ico | image/vnd.microsoft.icon | IANA-registered; image/x-icon is the common de-facto alias |
| .bmp | image/bmp | |
| .tif .tiff | image/tiff | |
| .heic | image/heic | iPhone photos; limited browser support |
| .heif | image/heif |
Audio
| Extension | MIME type | Notes |
|---|---|---|
| .mp3 | audio/mpeg | Not "audio/mp3" |
| .wav | audio/wav | De-facto standard; audio/x-wav also seen |
| .ogg .oga | audio/ogg | Ogg container with Vorbis or Opus inside |
| .opus | audio/ogg | Opus in Ogg; raw codec type is audio/opus |
| .m4a | audio/mp4 | AAC in an MP4 container |
| .aac | audio/aac | Raw AAC (ADTS) |
| .flac | audio/flac | |
| .weba | audio/webm | Audio-only WebM |
| .mid .midi | audio/midi |
Video
| Extension | MIME type | Notes |
|---|---|---|
| .mp4 | video/mp4 | The safest choice for web video |
| .webm | video/webm | VP9/AV1 + Opus |
| .ogv | video/ogg | |
| .mov | video/quicktime | QuickTime; patchy support outside Safari |
| .mkv | video/x-matroska | Unregistered but universal for Matroska |
| .avi | video/x-msvideo | |
| .wmv | video/x-ms-wmv | |
| .mpeg .mpg | video/mpeg | |
| .3gp | video/3gpp | Old mobile video |
| .m3u8 | application/vnd.apple.mpegurl | HLS playlist |
| .ts | video/mp2t | MPEG transport stream — HLS segments (not TypeScript!) |
Fonts
| Extension | MIME type | Notes |
|---|---|---|
| .woff2 | font/woff2 | The modern web font format — RFC 8081 |
| .woff | font/woff | |
| .ttf | font/ttf | |
| .otf | font/otf | |
| .eot | application/vnd.ms-fontobject | Legacy IE only — drop it |
Archives & packages
| Extension | MIME type | Notes |
|---|---|---|
| .zip | application/zip | |
| .gz | application/gzip | RFC 6713; also for .tar.gz / .tgz |
| .tar | application/x-tar | |
| .bz2 | application/x-bzip2 | |
| .xz | application/x-xz | |
| .zst | application/zstd | RFC 8878 |
| .7z | application/x-7z-compressed | |
| .rar | application/vnd.rar | |
| .jar | application/java-archive | |
| .apk | application/vnd.android.package-archive | Android package |
| .deb | application/vnd.debian.binary-package | Debian/Ubuntu package |
| .rpm | application/x-rpm | Red Hat package (unregistered but conventional) |
| .dmg | application/x-apple-diskimage | macOS disk image |
| .iso | application/x-iso9660-image | Optical disc image |
| .exe .msi | application/octet-stream | Or application/x-msdownload; both trigger a download |
| .bin (any binary) | application/octet-stream | The generic "just bytes" fallback |
Code & data
| Extension | MIME type | Notes |
|---|---|---|
| .js .mjs | text/javascript | RFC 9239 re-blessed text/javascript; application/javascript still works |
| .json | application/json | Never "text/json" — see mistakes below |
| .jsonld | application/ld+json | JSON-LD structured data |
| .ndjson .jsonl | application/x-ndjson | Newline-delimited JSON streams |
| .map | application/json | Source maps are plain JSON |
| .yaml .yml | application/yaml | Registered by RFC 9512 (2024); older servers send text/yaml |
| .toml | application/toml | |
| .wasm | application/wasm | Required exactly — streaming compilation fails on anything else |
| .webmanifest | application/manifest+json | PWA manifest |
| .rss | application/rss+xml | |
| .atom | application/atom+xml | |
| .sh | application/x-sh | Often served as text/plain to display instead of download |
| .py | text/x-python | Unregistered convention |
| .sql | application/sql | RFC 6922 |
| (form posts) | application/x-www-form-urlencoded | Default HTML form encoding |
| (file uploads) | multipart/form-data | Forms with files; parts carry their own types |
| (SSE streams) | text/event-stream | Server-Sent Events |
Structure of a MIME type
A media type is type/subtype, optionally followed by parameters: text/html; charset=utf-8. The top-level types you'll meet are text, image, audio, video, font, application (anything that doesn't fit elsewhere) and the composite multipart and message. Subtypes carry structure hints via suffixes — +json, +xml, +zip — so a parser that knows JSON can handle application/ld+json without knowing JSON-LD. Prefixes signal registration trees: vnd. for vendor types (like the Office formats above) and the legacy x- for unregistered types that stuck around.
The charset parameter
For text/* types, charset tells the receiver how bytes map to characters: Content-Type: text/html; charset=utf-8. Omit it and clients guess — historically defaulting to Latin-1, which is where "é" instead of "é" comes from. Always send charset=utf-8 on HTML, CSS, plain text and CSV. JSON doesn't need it: application/json is defined as UTF-8 (RFC 8259), and the parameter has no meaning there — though sending it is harmless.
Multipart types
multipart/* types bundle several bodies into one message, separated by a boundary string declared in the header: Content-Type: multipart/form-data; boundary=----abc123. Each part has its own headers, including its own Content-Type. multipart/form-data is how browsers upload files; multipart/mixed and multipart/alternative structure email (attachments; plain-text + HTML versions); multipart/byteranges answers multi-range requests. When using fetch with a FormData body, don't set Content-Type yourself — the browser must generate the boundary, and a hand-written header without it breaks parsing.
application/octet-stream — the fallback
application/octet-stream means "arbitrary bytes, no promises" — the correct type when you genuinely don't know what a file is. Browsers respond by downloading instead of rendering, which also makes it a deliberate choice for forcing downloads (usually paired with Content-Disposition: attachment). But it's a bug when it leaks onto known types: images won't display inline, PDFs download instead of opening, and WebAssembly won't compile. If your server sends octet-stream for a known extension, its MIME map needs an entry.
Common Content-Type mistakes
| Mistake | Why it bites | Fix |
|---|---|---|
| text/json | Not a registered type; strict parsers and frameworks reject or mishandle it | application/json |
| Missing charset on text/html | Clients guess the encoding — mojibake for any non-ASCII content | text/html; charset=utf-8 |
| application/font-woff2 | Never registered; the font tree replaced it | font/woff2 |
| ES modules as text/plain | Browsers enforce strict MIME checking for <script type="module"> — the script silently refuses to run | text/javascript |
| SVG as text/xml or octet-stream | <img src="x.svg"> shows nothing | image/svg+xml |
| .wasm as octet-stream | WebAssembly.instantiateStreaming() throws | application/wasm |
| JSON POST without Content-Type | Frameworks won't parse the body — req.body is empty or the API returns 415 | application/json |
| Manually setting multipart boundary | Hand-written multipart/form-data header lacks the real boundary; server can't split parts | Let the client library set it |
| Trusting Content-Type on uploads | The header is attacker-controlled — a PHP shell can claim to be image/png | Validate content server-side (magic bytes) |
Related: send X-Content-Type-Options: nosniff so browsers never second-guess your declared types — without it, MIME sniffing can turn a mislabeled upload into executed script.
About this reference
Types marked with RFCs are IANA-registered; a few entries (.mkv, .rpm, .py) are unregistered de-facto conventions, noted as such. When registered and de-facto names differ (like .ico), both are listed. Filtering runs entirely in your browser.
Related tools on this site: inspect what a server actually sends with the HTTP header analyzer, build requests with the right Content-Type using curl-to-code, and test endpoints live with the API tester.