MIME types and file extensions
Published: 2026-06-26
How type/subtype MIME labels relate to dotted file extensions, why HTTP uses Content-Type instead of filenames, and when the same format has more than one valid label.
MIME types (today usually called media types) are short strings like image/png or application/json that tell software what kind of data it is handling. File extensions (.png, .json) are a parallel convention baked into filenames. They often agree, but they are not the same mechanism—and treating them as interchangeable causes broken downloads, strict CSP failures, and “the server sent the wrong type” bugs.
MIME structure in one minute
A media type has a type/subtype pair, optionally followed by parameters:
type/subtype; parameter=value
Examples:
| MIME type | Typical meaning |
|---|---|
text/html |
HTML markup |
text/css |
Stylesheet |
image/jpeg |
JPEG image bytes |
application/json |
JSON document |
application/pdf |
PDF document |
application/octet-stream |
Generic binary (unknown or fallback) |
The type is a broad class (text, image, audio, video, application, font, …). The subtype narrows it (html, png, zip). Parameters add detail—most often charset=UTF-8 on text types so parsers know how to decode bytes into characters.
Extensions are not part of the MIME string. A file named report.pdf is still PDF because its bytes match the format; the .pdf suffix is a hint for humans and operating systems.
How extensions and MIME types relate
| Layer | What it is | Where it shows up |
|---|---|---|
| Filename extension | Suffix after the last dot (.wasm, .tar.gz is special) |
photo.jpg, “Save as type” dialogs, path.ext in URLs |
| MIME / media type | Registered or de-facto label for the byte stream | HTTP Content-Type, <input accept="…">, email attachments, clipboard formats |
| Magic bytes | Signature at the start of the file (89 50 4E 47 for PNG) |
File(1), browsers sniffing, security policies |
In the happy path, all three align: chart.png contains PNG bytes, the server sends Content-Type: image/png, and the browser renders an image.
When they diverge:
data.binwith JSON inside — extension says “binary”; MIME should beapplication/jsonif you want a JSON parser to accept it.script.jsserved astext/plain— the file extension looks like JavaScript, but withouttext/javascript(orapplication/javascript) the browser may not execute it..jpgvs.jpeg— two extensions, one image subtype:image/jpeg.
Extensions are hints. MIME in HTTP headers is the declared type for that response body. Sniffing (guessing from content) still happens in some clients, but relying on sniffing is fragile—especially with security headers that disable it.
Where MIME types matter for developers
HTTP responses
When your API or static host returns a body, set Content-Type to the correct type and charset:
Content-Type: application/json; charset=utf-8
Content-Type: text/html; charset=utf-8
Content-Type: image/svg+xml
Frameworks often guess from the filename when you forget; that guess can be wrong for uncommon extensions or generated files with no extension.
Uploads and forms
Multipart uploads carry a MIME part type per field. The browser may infer it from the selected file’s extension or OS metadata. Your server should still validate bytes, not trust the client label alone.
accept on file inputs
<input type="file" accept="image/png,image/jpeg,.pdf" />
You can list MIME types, extensions, or both. Matching is browser-dependent; MIME is more precise when you care about format families (e.g. image/*).
APIs and configuration
Object storage (S3, GCS), CDNs, and email clients store a content type metadata field separate from the key/path. A key ending in .html does not automatically set text/html unless your upload code or bucket policy does.
JSON, XML, and text formats
Structured text types are easy to get “almost right”:
- JSON is
application/json(UTF-8 by default in modern stacks). See What is JSON? for syntax; the MIME label tells clients to parse as JSON, not as HTML. - HTML is
text/html— distinct from plain text even when the file looks readable in an editor. - CSV is often
text/csv; TSV and logs may betext/plain.
Wrong labels can trigger XSS (HTML interpreted as document), broken fetch().json(), or download instead of inline display.
One extension, several MIME labels (and the reverse)
The IANA media types registry is authoritative, but real deployments disagree on edge cases:
| Format | Common extensions | MIME labels you may see |
|---|---|---|
| JavaScript | .js, .mjs, .cjs |
text/javascript, application/javascript, application/node (for .cjs in some tables) |
| JSON | .json |
application/json |
| ZIP-based Office | .docx, .xlsx |
Long application/vnd.openxmlformats-officedocument.* types |
| Unknown binary | .bin, .dll |
application/octet-stream |
application/octet-stream means “opaque bytes.” It is a safe default for downloads but tells the browser not to treat the payload as a specific format. Use it when you truly do not know, or when forcing a download; do not use it for JSON or HTML you expect the client to interpret.
Multiple extensions mapping to one MIME is normal (jpg / jpeg → image/jpeg). One extension with historically competing MIME strings is also normal—pick what your stack documents and stay consistent in tests.
Extensions without a dot, compound names, and case
- Lookup tools usually normalize
.PNGandpngto the same extension key. .tar.gzis one filename pattern with two format layers (tar inside gzip); MIME is oftenapplication/gzipfor the outer stream or a composite story depending on context.- No extension — common for
Dockerfile,Makefile, or Unix binaries; MIME must come from content or server config.
Content-Type is not encoding
Do not confuse media type with Content-Encoding (gzip, br) or with URL percent-encoding. A gzip-compressed JSON response might look like:
Content-Type: application/json; charset=utf-8
Content-Encoding: gzip
The body bytes are compressed; after decompression they are JSON. Similarly, hex dumps describe raw bytes for debugging—they do not replace a correct Content-Type on the wire.
Security and correctness pitfalls
- Trusting extension only —
evil.jpgcan contain script if served withtext/htmlor sniffed incorrectly. Validate content and set headers deliberately. - Missing charset on text —
text/plainwithout charset may be interpreted as Latin-1; UTF-8 text with mojibake is a common result. - Serving user uploads from your origin — wrong
Content-Typeon uploaded HTML/SVG enables stored XSS. UseContent-Disposition: attachmentor sanitize; prefer correct types for safe formats. - Strict MIME checks — service workers, module scripts, and some APIs require exact types (
application/wasmfor WebAssembly,text/javascriptfor classic scripts depending on policy). - Assuming the registry fits in your head — vendor-specific subtypes (
vnd.*,x-*) are long and numerous; use a reference table for copy-paste instead of memorizing.
When a local lookup table helps
Typical tasks:
- Set
Content-Typeon deploy for static files (wasm,webmanifest, fonts, favicons). - Fill
acceptattributes or API docs with the right type/subtype string. - Compare extensions when a client rejects a file (“is it
audio/mpegoraudio/mp3?”). - Work offline without hitting a third-party MIME API that logs your queries.
A curated subset focused on web and developer formats is enough for day-to-day work; the full IANA list is thousands of entries, many irrelevant to front-end and backend HTTP work.
Try it locally in your browser
Use the MIME Type Lookup tool to:
- Search by extension (with or without a leading dot) or by partial MIME string (
image/,json). - Filter by category (image, text, code, data, archive, …).
- Copy a dotted extension or full MIME value for headers, config, or docs.
- See a hint banner when your search looks like a type/subtype, listing common extensions mapped to that MIME in the bundled table.
The dataset ships with the page; searches stay in your browser and are not sent to a server. It is a practical reference, not the complete IANA registry—when standards bodies and browsers disagree, follow your target platform’s documentation and verify with a real request.
Related reading
- URL encoding vs form encoding — how HTTP represents field values and charsets alongside
Content-Type. - What is JSON? — syntax and the role of
application/jsonin APIs. - Hex encoding: UTF-8 bytes explained — inspecting raw bytes when MIME labels and content disagree.