My Tool Studio
Developer Tools·5 min read

What Is a MIME Type and Why Browsers Care

A user uploads a photo and your validator rejects it. A report link downloads a file that opens as gibberish. Both problems trace back to the same two words in an HTTP header. So what is a MIME type? It's the label that tells software what a stream of bytes contains, and browsers act on that label rather than on the bytes. This article explains how the labels are structured, how browsers act on them, what goes wrong when a server sends the wrong one, and how to check what a file really is, with .webp as the running example.

example.comFoundRegistrarNameCheap Inc.Created2016-04-12Expires2027-04-12StatusActive

Two familiar failures, one header behind both

First failure: your upload form accepts photos, a user picks a perfectly good image, and validation rejects it because the code checked for image/jpeg while the phone sent image/heic. Second failure: a PDF that should open in a browser tab downloads to disk instead, because the server labeled it application/octet-stream. Different symptoms, identical root cause: a mismatched label on the bytes.

Neither bug lives in your application logic. Both live in a header you may never have inspected directly. You can watch it yourself in about thirty seconds: open the Network panel, click the response, and read Content-Type under the headers section. Checking there usually settles whether the problem belongs to the file or to the label stuck on it.

What is a MIME type actually made of

Type, slash, subtype. That's the whole grammar.

A MIME type is a two-part label, type slash subtype, declaring what a sequence of bytes represents: text/html, image/png, application/json, font/woff2. The first part places the content in a broad family, the second names the precise format, and IANA maintains the official registry so every client and server shares one vocabulary. Parameters can follow a semicolon, as in text/html; charset=utf-8.

Files don't carry this label internally. Extensions hint at it, servers assert it in the Content-Type header, and everything downstream trusts the assertion. That chain of trust is the entire story of MIME debugging.

How browsers use content type before showing you anything

When a response arrives, the browser reads Content-Type first and picks a handler: render text/html as a page, paint image/webp into an img element, hand video/mp4 to the media player, and download application/octet-stream because arbitrary binary has no viewer. The actual bytes only get a vote in narrow sniffing cases, and the X-Content-Type-Options: nosniff header removes even that.

The header outranks the file extension completely. A URL ending in .png but served as text/plain is not a PNG as far as the browser is concerned.

One worked example: .webp with the wrong label

Look up .webp in the MIME Type Lookup and you get image/webp. Serve a WebP file under that header and an img tag renders it in every modern browser.

Now serve the same file as text/plain. Open the URL directly and the browser prints thousands of garbage glyphs, faithfully interpreting image bytes as text. Reference it from a page that sends nosniff and the image is blocked outright, with a console warning about the mismatch. Label it application/octet-stream instead and the browser downloads it rather than displaying it. Same bytes all three times; only the header changed, and the header won every time.

The fix is usually a single line of configuration. Nginx reads its mapping from a mime.types file, Apache uses AddType directives, and static hosts like S3 want the value set per object at upload time. Look the type up, set it once at the source, and this whole class of complaints disappears. Each row in the MIME Type Lookup has nginx and Apache buttons that copy that exact line, and the list downloads as a complete types block when you need many at once.

Checking what a file really is

The label can lie. The first bytes usually don't.

Most binary formats start with a fixed signature: PNG files begin with the bytes 89 50 4E 47, and PDFs begin with %PDF-. Drop a file, or up to 50 at once, on the checker at the top of the MIME Type Lookup and it reads the first 4 KB of each on your device, matches those signatures, and reports the detected type next to the type suggested by the extension and the type your browser reports. Nothing is uploaded.

When a JPEG has been renamed to .png, the checker shows a warning that the extension and content disagree, which is exactly the case an extension-only upload filter would miss. Text formats have no signature, so SVG and HTML are judged from how the text begins, and ZIP-based formats like .docx and .xlsx share one signature, so the extension decides between them. Press Copy header to get a ready line such as Content-Type: image/webp for your server config.

Wrong MIME type errors you'll actually see

These are the misconfigurations that generate real console errors and support tickets:

  • Failed to load module script: JavaScript modules refuse to run unless served with a JavaScript type, so a route that falls through to an HTML error page triggers exactly this message. The standard type is now text/javascript.
  • Uploads rejected on extension-to-type mismatches, the .heic photo failing a check that only allows image/jpeg and image/png.
  • SVG files rendering as raw text or being blocked, because they need image/svg+xml rather than a generic XML or text type.
  • Web fonts silently failing when .woff2 isn't served as font/woff2, often tangled up with CORS on a CDN.
  • Trusting the declared Content-Type for upload security. The client sets it freely, so verify file signatures server-side for anything that matters.

Faster lookups, in either direction

Run the search backwards when reading server configs: paste application/vnd.openxmlformats-officedocument.spreadsheetml.sheet into the box and it resolves to .xlsx, which beats deciphering the string by eye. Typing image/ lists every image extension at once, a quick start for an upload allowlist. And copy MIME strings with the Copy button instead of retyping them; the long Office types are where typos breed.

The tools you'll open next

Content type problems travel with companions. The HTTP Header Checker shows the Content-Type a live URL actually sends, and the HTTP Status Codes List matters when the response code, not the label, is what's off. The cURL to Code Converter rebuilds a request as runnable code once you've found the header to fix, so you can verify the change from a script. And if you're embedding small files as data URLs, Base64 Decode and Encode produces the payload that follows the MIME prefix in the URL.

Try it now

Open MIME Type Lookup

The tool is one click away. No sign up, no upload, no payment.

Open MIME Type Lookup