MIME Type Lookup
Developer Tools · Added
The Content-Type header is the only thing that tells a browser what a file actually is — the extension is a hint to the operating system and nothing more. Get it wrong and the failures are baffling rather than obvious: a stylesheet that is silently ignored, a font that never loads, a WebAssembly module that refuses to compile. Search by extension or by type, and get the header to send along with whether it needs a charset, whether compressing it is worth anything, and what its file signature is.
45 of 45 types
Text and markup
| Extension | Content-Type | Charset | Compress |
|---|---|---|---|
| .html .htm | text/htmlHTML document | utf-8 | Yes |
| .css | text/cssCascading style sheet | utf-8 | Yes |
| .js .mjs | text/javascriptJavaScript | utf-8 | Yes |
| .txt .log .text | text/plainPlain text | utf-8 | Yes |
| .csv | text/csvComma-separated values | utf-8 | Yes |
| .md .markdown | text/markdownMarkdown | utf-8 | Yes |
| .xml | text/xmlXML | utf-8 | Yes |
| .ics | text/calendariCalendar | utf-8 | Yes |
Application and data
| Extension | Content-Type | Charset | Compress |
|---|---|---|---|
| .json | application/jsonJSON | — | Yes |
| .jsonld | application/ld+jsonJSON-LD | — | Yes |
| application/pdfPDF | — | No | |
| .wasm | application/wasmWebAssembly | — | Yes |
| .bin .dat | application/octet-streamArbitrary binary | — | No |
| — | application/x-www-form-urlencodedForm encoding | — | Yes |
| — | multipart/form-dataMultipart form | — | No |
| .docx | application/vnd.openxmlformats-officedocument.wordprocessingml.documentWord document | — | No |
| .xlsx | application/vnd.openxmlformats-officedocument.spreadsheetml.sheetExcel spreadsheet | — | No |
| .rtf | application/rtfRich text | — | Yes |
| .sql | application/sqlSQL script | utf-8 | Yes |
Images
| Extension | Content-Type | Charset | Compress |
|---|---|---|---|
| .jpg .jpeg .jpe | image/jpegJPEG image | — | No |
| .png | image/pngPNG image | — | No |
| .gif | image/gifGIF image | — | No |
| .webp | image/webpWebP image | — | No |
| .avif | image/avifAVIF image | — | No |
| .svg | image/svg+xmlSVG image | utf-8 | Yes |
| .ico | image/x-iconIcon | — | No |
| .tif .tiff | image/tiffTIFF image | — | No |
| .heic | image/heicHEIC image | — | No |
Audio
| Extension | Content-Type | Charset | Compress |
|---|---|---|---|
| .mp3 | audio/mpegMP3 audio | — | No |
| .wav | audio/wavWAV audio | — | Yes |
| .ogg .oga | audio/oggOgg audio | — | No |
| .flac | audio/flacFLAC audio | — | No |
| .aac .m4a | audio/aacAAC audio | — | No |
Video
| Extension | Content-Type | Charset | Compress |
|---|---|---|---|
| .mp4 .m4v | video/mp4MP4 video | — | No |
| .webm | video/webmWebM video | — | No |
| .mov | video/quicktimeQuickTime video | — | No |
Fonts
| Extension | Content-Type | Charset | Compress |
|---|---|---|---|
| .woff2 | font/woff2WOFF2 font | — | No |
| .woff | font/woffWOFF font | — | No |
| .ttf | font/ttfTrueType font | — | Yes |
| .otf | font/otfOpenType font | — | Yes |
Archives
| Extension | Content-Type | Charset | Compress |
|---|---|---|---|
| .zip | application/zipZIP archive | — | No |
| .gz | application/gzipGzip archive | — | No |
| .tar | application/x-tarTar archive | — | Yes |
| .7z | application/x-7z-compressed7-Zip archive | — | No |
| .rar | application/vnd.rarRAR archive | — | No |
The Content-Type header is the only thing that tells a browser what a file is — the extension is a hint to the operating system and nothing more. A stylesheet served as text/plain is ignored in standards mode, a WebAssembly module refuses to stream-compile under any type but application/wasm, and a font sent as octet-stream simply fails to load. When something mysteriously does not work, the header is the first thing to check.
How to use the mime type lookup
- 1Type an extension, a full MIME type, or a filename into the search box.
- 2An exact match appears at the top with the complete header to send.
- 3Check the charset row — text formats need one and binary formats must not have one.
- 4Check the compression row before configuring gzip or Brotli: already-compressed formats gain nothing.
- 5Use the file signature where you are validating uploads, since an extension can be renamed and the leading bytes cannot.
Examples
A stylesheet
- Input
- .css
- Result
- Content-Type: text/css; charset=utf-8
In standards mode a browser refuses a stylesheet sent as anything else, which produces an unstyled page and no obvious error.
JSON, and the charset trap
- Input
- application/json
- Result
- No charset parameter — JSON is defined as UTF-8
RFC 8259 fixes the encoding, so adding a charset is redundant and technically invalid.
A font
- Input
- .woff2
- Result
- font/woff2, and not worth compressing
WOFF2 is Brotli-compressed internally. Running gzip over it costs CPU to make the file very slightly larger.
About the mime type lookup
How a type gets decided, and where it goes wrong
For a static file, the web server looks up the extension in a table and sets the header. That table is usually `mime.types` for nginx or `mime.conf` for Apache, and it is where a missing entry causes trouble: an unrecognised extension falls back to application/octet-stream, which downloads rather than displays. Adding a new format to a site — a WOFF2 font, an AVIF image, a WebAssembly module — often means adding it to that table first.
For a dynamic response the application sets the header itself, and the common failure there is forgetting. A framework's default of text/html applied to a JSON API response will work in most clients and break the strict ones, and it defeats any content negotiation downstream.
The third source of trouble is a CDN or proxy that rewrites or drops the header. Anything that re-serves content has an opportunity to change what it claims to be, and a mismatch between what the origin sent and what arrives is worth checking whenever a file works locally and not in production.
Sniffing, and why it is switched off
Browsers historically guessed a file's type from its content when the header looked wrong, which was helpful in an era of badly configured servers and is a security problem now. If a user can upload a file that a site serves back, and the browser is willing to sniff it as HTML regardless of the declared type, then an uploaded file becomes a script running on the site's own origin.
The fix is the `X-Content-Type-Options: nosniff` header, which tells the browser to trust the declared type and refuse to guess. It is close to universal on well-configured sites now, and it raises the stakes on getting the type right: with sniffing disabled, a stylesheet sent as text/plain is not quietly rescued, it is simply not applied.
The practical consequence is that the Content-Type header has gone from a hint to a contract. It is worth checking with `curl -I` when something behaves oddly, because a wrong type produces symptoms that look like almost anything else — a caching problem, a build failure, a broken file — and almost never looks like what it is.
Frequently asked questions
Is the extension or the Content-Type authoritative?
When should I add charset=utf-8?
Why should I not compress images and video?
What are magic bytes and why would I check them?
Why do some types have more than one name?
Related tools
HTTP Status Code Lookup
Developer Tools
Search every HTTP status code — what it means, when to return it, and whether it caches.
Image to Base64
Image Tools
Turn an image into a Base64 data URI ready to paste into CSS or HTML.
JSON Formatter
Developer Tools
Pretty-print, minify and inspect JSON with precise error positions.