My Tool Studio
Developer Tools·4 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, because the bytes themselves carry no type information at all. This article explains how the labels are structured, how browsers act on them, and what goes wrong when a server sends the wrong one, 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.

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 table 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 here, set it once at the source, and this whole class of complaints disappears.

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.
  • Uploads rejected on extension-to-type mismatches, the .heic photo failing a check that only whitelists 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. Use the group column when building upload whitelists, since allowing everything in the Image group translates directly into an allowlist. And copy MIME strings with the click-to-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 Status Codes reference matters when the response code, not the label, is what's off. cURL to Code 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, the Base64 Encoder / Decoder 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