MIME types and file extensions
A searchable list of MIME content types and their file extensions, with notes on the ones servers routinely get wrong.
- Runs in your browser
- Nothing you enter is sent
- Free, no account
Showing 71 entries.
| Extension | MIME type | Notes | Copy |
|---|---|---|---|
| .txt .log .text | text/plain | Plain textAdd `; charset=utf-8` — without it, browsers guess, and old ones guess Latin-1. | |
| .html .htm | text/html | HTML document | |
| .css | text/css | Cascading style sheetServing CSS as text/plain makes browsers refuse it under X-Content-Type-Options: nosniff. | |
| .js .mjs | text/javascript | JavaScriptThe IANA-registered type. application/javascript is obsolete but still widely accepted. | |
| .csv | text/csv | Comma-separated valuesExcel opens text/csv inline; add Content-Disposition: attachment to force a download. | |
| .md .markdown | text/markdown | Markdown | |
| .ics | text/calendar | iCalendar | |
| .vcf | text/vcard | vCard contact | |
| .xml | text/xml | XML (human-readable)Prefer application/xml unless the document is genuinely meant to be read as text. | |
| .tsv | text/tab-separated-values | Tab-separated values | |
| — | text/event-stream | Server-sent eventsMust not be buffered by a proxy or the stream never arrives. | |
| .jpg .jpeg .jpe | image/jpeg | JPEG imageimage/jpg is not a real type — some servers send it, but it is wrong. | |
| .png | image/png | PNG image | |
| .gif | image/gif | GIF image | |
| .webp | image/webp | WebP image | |
| .avif | image/avif | AVIF image | |
| .svg | image/svg+xml | SVG vector imageSVG can contain script. Serve user-uploaded SVG from a separate origin or with a strict CSP. | |
| .ico | image/x-icon | Windows iconimage/vnd.microsoft.icon is the registered type; image/x-icon is what everything sends. | |
| .bmp | image/bmp | Bitmap image | |
| .tif .tiff | image/tiff | TIFF image | |
| .heic | image/heic | HEIC imageiPhone default. Only Safari decodes it natively. | |
| .apng | image/apng | Animated PNG | |
| .mp3 | audio/mpeg | MP3 audioNot audio/mp3 — that type does not exist. | |
| .wav | audio/wav | WAV audioaudio/x-wav and audio/wave also appear in the wild. | |
| .ogg .oga | audio/ogg | Ogg audio | |
| .weba | audio/webm | WebM audio | |
| .aac | audio/aac | AAC audio | |
| .m4a | audio/mp4 | MPEG-4 audio | |
| .flac | audio/flac | FLAC audio | |
| .opus | audio/opus | Opus audio | |
| .mp4 .m4v | video/mp4 | MPEG-4 videoAdd `#t=0.1` or a poster if the first frame is black — that is a container issue, not a MIME one. | |
| .webm | video/webm | WebM video | |
| .mov | video/quicktime | QuickTime video | |
| .avi | video/x-msvideo | AVI video | |
| .mkv | video/x-matroska | Matroska video | |
| .mpeg .mpg | video/mpeg | MPEG video | |
| .ogv | video/ogg | Ogg video | |
| .json | application/json | JSONNo charset parameter is defined — JSON is always UTF-8. | |
| .jsonld | application/ld+json | JSON-LD | |
| .xml | application/xml | XML | |
| application/pdf | PDF document | ||
| .zip | application/zip | ZIP archive | |
| .gz | application/gzip | Gzip archive | |
| .tar | application/x-tar | Tar archive | |
| .7z | application/x-7z-compressed | 7-Zip archive | |
| .rar | application/vnd.rar | RAR archive | |
| .bin | application/octet-stream | Arbitrary binary dataThe fallback when nothing is known. Browsers download rather than display it. | |
| — | application/x-www-form-urlencoded | URL-encoded form data | |
| — | multipart/form-data | Multipart form dataRequired for file uploads. Never set the boundary yourself — let the client library do it. | |
| .wasm | application/wasm | WebAssembly moduleRequired for WebAssembly.instantiateStreaming(); the wrong type makes it fall back or fail. | |
| .webmanifest | application/manifest+json | Web app manifest | |
| .rss | application/rss+xml | RSS feed | |
| .atom | application/atom+xml | Atom feed | |
| .yaml .yml | application/yaml | YAML | |
| .sql | application/sql | SQL script | |
| .ndjson .jsonl | application/x-ndjson | Newline-delimited JSON | |
| .doc | application/msword | Word 97–2003 | |
| .docx | application/vnd.openxmlformats-officedocument.wordprocessingml.document | Word document | |
| .xls | application/vnd.ms-excel | Excel 97–2003 | |
| .xlsx | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet | Excel workbook | |
| .ppt | application/vnd.ms-powerpoint | PowerPoint 97–2003 | |
| .pptx | application/vnd.openxmlformats-officedocument.presentationml.presentation | PowerPoint presentation | |
| .odt | application/vnd.oasis.opendocument.text | OpenDocument text | |
| .ods | application/vnd.oasis.opendocument.spreadsheet | OpenDocument spreadsheet | |
| .epub | application/epub+zip | EPUB e-book | |
| .rtf | application/rtf | Rich Text Format | |
| .woff | font/woff | WOFF font | |
| .woff2 | font/woff2 | WOFF2 fontThe only web font format worth serving in 2026 — every current browser supports it. | |
| .ttf | font/ttf | TrueType font | |
| .otf | font/otf | OpenType font | |
| .eot | application/vnd.ms-fontobject | Embedded OpenTypeInternet Explorer only. Safe to drop. |
Your lookup never leaves this tab — check it yourself—
Starting the network probe…
The counter above wraps fetch, XMLHttpRequest and navigator.sendBeacon in this tab and counts every call. It does not block anything — it just reports.
Two ways to verify independently
- Turn off Wi-Fi or enable airplane mode, then use the tool. It keeps working, because the page is already fully loaded.
- Open your browser devtools, switch to the Network tab, clear it, and run the tool. No new row appears.
Why this matters
In 2025 researchers found that popular online formatters had retained tens of thousands of user-submitted snippets — JSONFormatter.org and CodeBeautify together exposed roughly 80,000 saved documents, many containing live cloud credentials, private keys and internal database connection strings, because “format this” quietly meant “upload this”. A separate incident exposed roughly 3.5 million user PDFs on a document-conversion service. The only structural fix is not sending the data in the first place: this site is served under a Content-Security-Policy whose connect-src contains no third-party origin, so a request off this device cannot be made even by accident.
What a MIME type is and where it comes from
A MIME type — formally a media type — is a two-part label, type/subtype,
that tells a client what a stream of bytes is. On the web it arrives in the
Content-Type response header, and it is the only authoritative
signal. The file extension is a hint for the server, not for the browser; a file called
photo.png served as text/plain displays as gibberish.
Types are registered with IANA. Anything beginning x- or vnd. is
unregistered or vendor-specific — image/x-icon, application/vnd.rar —
which is why those two prefixes appear so often in the list.
The five that break things most often
| Wrong | Right | Symptom |
|---|---|---|
image/jpg | image/jpeg | Some strict clients refuse the image; image/jpg has never existed |
audio/mp3 | audio/mpeg | Playback fails in Safari and some Android browsers |
text/plain for JS | text/javascript | Script refused under X-Content-Type-Options: nosniff |
application/octet-stream for wasm | application/wasm | instantiateStreaming throws |
No charset on text/html | text/html; charset=utf-8 | Accented characters render as mojibake |
Content sniffing, and why nosniff exists
Historically browsers guessed the type when the header looked wrong, by examining the first bytes.
That guess is a security hole: an uploaded file declared as text/plain but sniffed as
text/html becomes stored cross-site scripting.
X-Content-Type-Options: nosniff turns the guessing off. It is the right header to send
and it is also why a MIME type that used to “work” suddenly stops after a security
review: the browser was covering for the misconfiguration, and now it will not. Serve the correct
type and the problem disappears permanently.
The charset parameter
text/*— always add it. The historical default is not UTF-8, and without the parameter older browsers and some tools fall back to Latin-1.application/json— never add it. The JSON specification fixes the encoding as UTF-8 and defines no charset parameter. Some strict parsers reject a request that includes one.- Binary types — irrelevant. There is no text to decode.
Uploads: never trust the client’s type
The Content-Type on a multipart upload is set by the browser from the file extension,
and an attacker can set it to anything. Validate server-side by reading the file’s magic
bytes — %PDF, \x89PNG, PK\x03\x04 for anything
zip-based including .docx and .xlsx — and re-derive the type yourself. Then serve user content from
a separate origin with Content-Disposition: attachment where you can.
Forcing a download
Keep the correct type and add a disposition header:
Content-Type: text/csv; charset=utf-8
Content-Disposition: attachment; filename="report-2026-08.csv"
Deliberately mislabelling the file as application/octet-stream also triggers a
download, but it breaks anything that inspects the type — previewers, virus scanners, and the
operating system’s choice of application. Use the disposition header instead.
Multipart and the boundary
multipart/form-data is the only type where you must not set the header by hand. It
carries a boundary parameter that has to match the delimiter used in the body, and the
HTTP client generates both together. Setting Content-Type: multipart/form-data
manually on a fetch with a FormData body strips the generated boundary
and the server sees an empty form — one of the most common upload bugs there is.
Questions
Why does the Content-Type header matter so much?
Because it is the only thing telling the browser what a response is. Serve JavaScript as `text/plain` and, under `X-Content-Type-Options: nosniff`, the browser refuses to execute it. Serve a font as `application/octet-stream` and it downloads instead of loading. Almost every "it works locally but not in production" static-asset bug is a MIME type.
Which types are most often wrong?
Four recur constantly. `image/jpg` does not exist — it is `image/jpeg`. `audio/mp3` does not exist — it is `audio/mpeg`. WebAssembly must be `application/wasm` or streaming instantiation fails. And `application/javascript` is superseded by `text/javascript`, though both work.
Should I add a charset?
For `text/*` yes — `text/html; charset=utf-8` — because the default without it is not UTF-8 and older browsers will mis-decode accented characters. For `application/json` no: the JSON specification fixes the encoding as UTF-8 and defines no charset parameter.
How do I force a download instead of displaying inline?
Keep the correct MIME type and add `Content-Disposition: attachment; filename="report.csv"`. Deliberately mislabelling the file as `application/octet-stream` also works but breaks anything that inspects the type.