MIME Type Reference
A reference table of MIME types (media types), which identify what a file is. Use it when configuring a web server, setting Content-Type headers or validating uploads.
What a MIME type is
MIME (Multipurpose Internet Mail Extensions) types are the standard way to identify the format and nature of a file. They are written as type/subtype and tell browsers and servers how to handle the content. You set them in the Content-Type header of an HTTP response and in attributes such as HTML's <input type="file" accept="...">.
Images (image)
| Extension | MIME type | Meaning |
|---|---|---|
| .jpg / .jpeg | image/jpeg | JPEG image. Lossy compression, ideal for photographs |
| .png | image/png | PNG image. Lossless with transparency support |
| .gif | image/gif | GIF image. Animated, limited to 256 colours |
| .webp | image/webp | WebP image. Google's high-compression format |
| .avif | image/avif | AVIF image. Next-generation format based on AV1 |
| .svg | image/svg+xml | SVG vector image. XML-based |
| .ico | image/x-icon | Icon file, used for favicons and the like |
| .bmp | image/bmp | Bitmap image. Uncompressed |
| .tiff / .tif | image/tiff | TIFF image, used in printing and DTP |
Documents (application)
| Extension | MIME type | Meaning |
|---|---|---|
application/pdf | PDF document | |
| .doc | application/msword | Microsoft Word (legacy) |
| .docx | application/vnd.openxmlformats-officedocument.wordprocessingml.document | Microsoft Word (OOXML) |
| .xls | application/vnd.ms-excel | Microsoft Excel (legacy) |
| .xlsx | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet | Microsoft Excel (OOXML) |
| .ppt | application/vnd.ms-powerpoint | Microsoft PowerPoint (legacy) |
| .pptx | application/vnd.openxmlformats-officedocument.presentationml.presentation | Microsoft PowerPoint (OOXML) |
Text (text)
| Extension | MIME type | Meaning |
|---|---|---|
| .txt | text/plain | Plain text |
| .html / .htm | text/html | HTML document |
| .css | text/css | CSS stylesheet |
| .csv | text/csv | Comma-separated text |
| .xml | text/xml | XML document |
| .js | text/javascript | JavaScript (application/javascript is also valid) |
| .json | application/json | JSON data |
| .md | text/markdown | Markdown text |
Audio (audio)
| Extension | MIME type | Meaning |
|---|---|---|
| .mp3 | audio/mpeg | MP3 audio. The most widely used audio format |
| .wav | audio/wav | WAV audio. Uncompressed PCM |
| .ogg | audio/ogg | Ogg Vorbis audio |
| .flac | audio/flac | FLAC audio. Lossless |
| .aac | audio/aac | AAC audio. The successor to MP3 |
| .webm | audio/webm | WebM audio |
| .m4a | audio/mp4 | MPEG-4 audio |
Video (video)
| Extension | MIME type | Meaning |
|---|---|---|
| .mp4 | video/mp4 | MP4 video. The most widely used video format |
| .webm | video/webm | WebM video. An open format built for the web |
| .avi | video/x-msvideo | AVI video |
| .mov | video/quicktime | QuickTime video |
| .mkv | video/x-matroska | Matroska video container |
| .mpeg | video/mpeg | MPEG video |
Archives and compression (application)
| Extension | MIME type | Meaning |
|---|---|---|
| .zip | application/zip | ZIP archive |
| .gz / .gzip | application/gzip | Gzip-compressed file |
| .tar | application/x-tar | tar archive |
| .tar.gz | application/gzip | tar archive compressed with gzip |
| .rar | application/vnd.rar | RAR archive |
| .7z | application/x-7z-compressed | 7-Zip archive |
| .bz2 | application/x-bzip2 | Bzip2-compressed file |
Fonts (font)
| Extension | MIME type | Meaning |
|---|---|---|
| .woff | font/woff | Web Open Font Format |
| .woff2 | font/woff2 | WOFF2. Better compression than WOFF |
| .ttf | font/ttf | TrueType font |
| .otf | font/otf | OpenType font |
Other
| Extension | MIME type | Meaning |
|---|---|---|
| (unknown) | application/octet-stream | Generic binary data. The default for unknown formats |
| .wasm | application/wasm | WebAssembly binary |
Working with MIME types
Server configuration
A web server such as Apache or Nginx maps file extensions to MIME types. Get that mapping wrong and the browser cannot handle the file properly — a .webp without the right type, for instance, is offered as a download instead of being displayed as an image.
Validating uploads
When you build an upload feature, check the MIME type as well as the extension. The MIME type can still be forged on the client, though, so for security you should also verify the magic bytes at the start of the file.
The Content-Type header
Set an accurate Content-Type on API responses and file downloads: application/json for JSON, text/csv for CSV. When the encoding needs to be explicit, append a charset parameter, as in text/html; charset=utf-8.
Declaring MIME types in server configuration
Below are the snippets you reach for when serving modern formats — WebP, AVIF, WASM, web fonts — that are often missing from a server's default mapping.
Apache .htaccess
# Modern image formats
AddType image/webp .webp
AddType image/avif .avif
AddType image/svg+xml .svg .svgz
# Fonts — cache these aggressively
AddType font/woff .woff
AddType font/woff2 .woff2
# WebAssembly and the modern JSON variants
AddType application/wasm .wasm
AddType application/manifest+json .webmanifest
AddType application/ld+json .jsonld
# Serve text as UTF-8
AddCharset utf-8 .html .css .js .json .xml
Nginx (overriding mime.types)
types {
image/webp webp;
image/avif avif;
application/wasm wasm;
application/manifest+json webmanifest;
}
# Force a charset on text/* and application/json
charset utf-8;
charset_types text/css text/plain text/xml application/javascript application/json application/xml;
PHP — emitting Content-Type
// Download a PDF under a given filename
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="invoice.pdf"');
readfile($path);
// JSON API response — always state the charset
header('Content-Type: application/json; charset=utf-8');
echo json_encode($data, JSON_UNESCAPED_UNICODE);
Node.js / Express
// Express infers Content-Type from res.type() or the extension
app.get('/data.json', (req, res) => {
res.type('application/json').send({ ok: true });
});
// Stream a file with an explicit MIME type
app.get('/report.csv', (req, res) => {
res.set('Content-Type', 'text/csv; charset=utf-8');
fs.createReadStream('report.csv').pipe(res);
});
Python — Flask / FastAPI
# Flask
from flask import Response
return Response(csv_text, mimetype='text/csv', headers={'Content-Disposition': 'attachment; filename="data.csv"'})
# FastAPI
from fastapi.responses import Response
return Response(content=json_str, media_type='application/json')
Go — net/http
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.Header().Set("X-Content-Type-Options", "nosniff") // Security — see below
json.NewEncoder(w).Encode(data)
Security: why you need X-Content-Type-Options: nosniff
Browsers have historically sniffed the contents of a file to guess its type whenever the Content-Type header was missing or wrong. That is a known attack vector: if a file uploaded as image/jpeg is really HTML containing a <script> tag, the browser may sniff it as HTML and execute the script.
Send X-Content-Type-Options: nosniff on every response. It tells the browser to trust the Content-Type the server declared instead of guessing. It is essential for user-uploaded files and JSON APIs, where attackers try to get JSON reinterpreted as HTML or JavaScript.
Upload validation — the three-layer rule
- Extension check — fast, but defeated by renaming the file. Treat it as a UX hint, nothing more.
- The MIME type the client sends (the
Content-Typeinside the multipart boundary) — just as easy to forge. The browser derives it from the file extension anyway. - Magic-byte (file signature) detection — read the actual leading bytes and match them against the known signature (
FF D8 FFfor JPEG,89 50 4E 47for PNG). This is the only layer you can trust. See the magic byte reference for details.
The rule in production: do all three. Use the first two as cheap filters that reject obvious junk, and the third as the authoritative check.
Frequently asked questions
What is the difference between application/json and text/json?
application/json is the official, IANA-registered type defined in RFC 8259. text/json was an unofficial spelling used by a few early servers; it was never registered and should be avoided. Because the JSON spec mandates UTF-8, a charset parameter is technically redundant — harmless if you state it, but unnecessary.
.webp and .avif files download instead of displaying
The server has no mapping for that extension and falls back to application/octet-stream, so the browser decides it is unknown binary data and offers a download. Add the image/webp and image/avif mappings to your Apache or Nginx configuration (see the snippets above).
Can I trust the MIME type the browser sends when validating uploads?
No. The browser derives the MIME type purely from the extension at selection time, so renaming malware.exe to cute-cat.jpg makes it report image/jpeg without hesitation. Always combine all three layers: extension, client MIME and magic-byte detection.
Which MIME type should I use for files the server does not recognise?
application/octet-stream. It is explicitly defined as arbitrary binary data and is the safe default: the browser will not try to render it, it offers a download instead, which prevents accidental execution.
What is the x- prefix in application/x-www-form-urlencoded?
Historically x- marked a type as experimental or non-standard. RFC 6648 retired the convention in 2012, but widely deployed types such as application/x-www-form-urlencoded, image/x-icon and application/x-tar kept the prefix for backward compatibility.
Should I add charset to binary types such as images and PDFs?
No. charset only means anything for text-based types — text/*, application/json, application/xml. On image/jpeg or application/pdf it carries no meaning, and some intermediaries such as CDNs and proxies strip it anyway.