Comprehensive reference for mime types reference covering essential concepts, practical examples, and production best practices.
Mime types define how data is structured, interpreted, and transmitted across systems. They are essential when sending files over HTTP, embedding resources in emails, serving web content, or processing data in pipelines. A misconfigured mime type can cause browsers to render HTML as plain text, APIs to reject JSON payloads, or mobile apps to fail loading images. This reference details the structure, usage, and common pitfalls of MIME types across real-world engineering workflows.
A MIME type is a two-part identifier: type/subtype, such as application/json, image/png, or text/html. These types are registered with the IANA and used universally across protocols and systems. The most common ways to determine a MIME type are through file extensions, content inspection, and explicit configuration.
File extensions are the simplest way to infer MIME types. Systems often use a mapping table to associate common extensions with types. For example:
.txt → text/plain
.html → text/html
.json → application/json
.png → image/png
.mp4 → video/mp4
.pdf → application/pdf
In a web server, the mapping is typically configured in a file or in a server-specific format. For example, in NGINX:
location / {
types {
text/html html htm;
text/css css;
application/javascript js;
image/png png;
image/jpeg jpeg jpg;
application/json json;
application/pdf pdf;
}
}
When a request arrives for /styles.css, the server checks the types block and assigns text/css to the response.
When a file has no extension or the extension is ambiguous, systems use the first few bytes of the file—called *magic numbers*—to determine the MIME type. This is especially important for binary formats.
For instance, a PNG file begins with the 8-byte signature:
89 50 4E 47 0D 0A 1A 0A
A JPEG starts with:
FF D8 FF E0
The file command from the command line uses these signatures:
$ file document.pdf
document.pdf: PDF document, version 1.4
$ file image.jpg
image.jpg: JPEG image data, JFIF standard 1.01
$ file data.json
data.json: JSON data
The file command is widely available and used in CI/CD pipelines to validate uploaded files:
for file in *.upload; do
mime=$(file -b --mime-type "$file")
if [[ "$mime" != "application/json" ]]; then
echo "Error: Expected application/json, got $mime for $file"
exit 1
fi
done
In HTTP responses, the Content-Type header explicitly sets the MIME type. This header is critical when serving content dynamically or when the content does not match the file extension.
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 154
{
"name": "Alice",
"age": 30
}
In a backend service, this is often set via a framework or middleware. In Node.js with Express:
app.get('/api/users/:id', (req, res) => {
const user = getUserById(req.params.id);
res.setHeader('Content-Type', 'application/json; charset=utf-8');
res.send(JSON.stringify(user));
});
In Go with net/http:
func handler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
json.NewEncoder(w).Encode(map[string]string{"message": "hello"})
}
The most common failure is assuming that a file extension determines the MIME type, but the actual content does not match. For example, a file named data.xml might contain JSON, causing clients to fail parsing it.
To detect and validate MIME types in production, use curl to inspect responses:
$ curl -I https://api.example.com/users/1
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 84
Date: Mon, 01 Apr 2024 12:00:00 GMT
A common mistake is omitting the charset parameter, leading to text being interpreted with the wrong encoding:
Content-Type: application/json
This implies UTF-8 by default, but if the actual content uses ISO-8859-1, the client may misread multibyte characters.
text/plain → plain text
text/html → HTML document
text/css → CSS stylesheet
text/csv → comma-separated values
text/xml → XML document
text/markdown → Markdown source
HTML files often include a charset parameter:
Content-Type: text/html; charset=utf-8
image/jpeg → JPEG image
image/png → PNG image
image/gif → GIF animation
image/webp → WebP image
image/svg+xml → Scalable Vector Graphics
video/mp4 → MP4 video
video/webm → WebM video
audio/mpeg → MP3 audio
audio/wav → WAV audio
application/ogg → Ogg container (audio/video)
For images, the image/* wildcard is frequently used in Accept headers:
Accept: image/webp, image/apng, image/*;q=0.8
application/json → JSON data
application/xml → XML data
application/zip → ZIP archive
application/x-tar → Tar archive
application/pdf → PDF document
application/octet-stream → raw binary data
application/ld+json → JSON-LD (Linked Data)
application/geo+json → GeoJSON
application/vnd.api+json → JSON API (e.g., JSON:API standard)
The application/octet-stream is the default fallback for unknown binary data. It is used when no specific MIME type is known, such as in file uploads or binary payloads.
application/x-www-form-urlencoded → HTML form data
multipart/form-data → form data with file uploads
application/x-gzip → GZIP-compressed data
application/x-tar.gz → Tarball compressed with GZIP
application/zip → ZIP archive (as above)
application/msgpack → MessagePack binary serialization
application/cbor → Concise Binary Object Representation
For file uploads in HTTP, multipart/form-data is the standard. A typical request includes:
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="avatar"; filename="profile.jpg"
Content-Type: image/jpeg
[binary data of the image]
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="description"
Content-Type: text/plain
Welcome to my profile!
------WebKitFormBoundary7MA4YWxkTrZu0gW--
application/javascript → JavaScript source code
text/javascript → alternate for JavaScript
application/ecmascript → ES module format
application/x-typescript → TypeScript source
application/json → JSON, as above
application/ld+json → Linked Data JSON
In a modern web application, JavaScript files are served with application/javascript:
HTTP/1.1 200 OK
Content-Type: application/javascript; charset=utf-8
Content-Length: 1024
ETag: "abc123"
Cache-Control: public, max-age=31536000
// index.js
export function greet(name) {
return `Hello, ${name}!`;
}
font/woff → WOFF font
font/woff2 → WOFF2 font
font/ttf → TrueType font
font/otf → OpenType font
application/x-font-ttf → alternate for TTF
application/x-font-woff → alternate for WOFF
text/x-component → Web Components manifest
application/manifest+json → Web App Manifest
These are crucial for performance. Browsers use font MIME types to load and render text efficiently.
When a user uploads a file, the client sends the Content-Type header based on the file extension. But the server may use the actual content to override it.
For example, a file named report.xlsx contains JSON:
{
"title": "Monthly Report",
"data": [1, 2, 3]
}
The client sends:
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
But the server expects application/json. The API fails to parse the payload.
The fix is to use file to validate uploads:
$ file -b --mime-type report.xlsx
application/json
A JSON response with Content-Type: application/json but no charset parameter implies UTF-8. But if the actual text contains non-ASCII characters like café, résumé, or naïve, the client may fail to decode them.
The correct header is:
Content-Type: application/json; charset=utf-8
Omitting charset=utf-8 causes subtle, hard-to-diagnose bugs in internationalized applications.
When a server receives a file with an unknown extension, it often falls back to application/octet-stream. This is acceptable for raw binary data but problematic for structured formats.
For example, a .config file with JSON content:
{
"database": "postgresql",
"port": 5432
}
If the server sends:
Content-Type: application/octet-stream
Clients may not recognize the content as JSON, leading to failed parsing or incorrect rendering.
When multiple mechanisms apply, the order of precedence matters. For example:
data.xml<?xml → application/xmlContent-Type: text/xmlThe final MIME type is determined by the order:
types block, it may override the Content-Type header.Accept headers, it may expect a specific type.A common failure is sending text/xml for XML data, but the server expects application/xml because it uses a different MIME type mapping.
In static file servers (e.g., NGINX, Apache, or python -m http.server), the MIME type is often inferred from extensions, but the mapping is incomplete or outdated.
For example, a server might not know image/webp, so .webp files get application/octet-stream instead of image/webp.
To debug, use curl -I to inspect the response:
$ curl -I http://example.com/images/header.webp
HTTP/1.1 200 OK
Content-Type: application/octet-stream
Content-Length: 12345
The fix is to update the server configuration or use the file command to generate a complete MIME type database.
APIs often use application/json for all responses, but this can be too coarse.
A better practice is to use application/vnd.api+json for REST APIs that follow the JSON:API standard. This allows clients to detect the API format and use it accordingly.
In a request:
Accept: application/vnd.api+json, application/json; q=0.9
The server responds with:
Content-Type: application/vnd.api+json
The client can then use the specific structure of the JSON:API format.
| MIME Type | Purpose | Common Usage |
|---|---|---|
text/html | HTML documents | Web pages |
text/css | CSS stylesheets | Web styling |
application/json | JSON data | APIs, config files |
application/xml | XML documents | Web services, data exchange |
image/png | PNG images | Web graphics |
image/jpeg | JPEG images | Photos, thumbnails |
application/pdf | PDF documents | Reports, forms |
multipart/form-data | Form data with files | File uploads |
application/javascript | JavaScript code | Client-side scripts |
application/zip | ZIP archives | Bundled files |
application/octet-stream | Raw binary data | Generic binary payloads |
These types, combined with standard patterns for setting and validating MIME types across HTTP, file systems, and APIs, form the backbone of data interchange in modern systems.
This page was rewritten on 14 October 2026. It replaced a templated version that was not specific to its own title. How these pages are written and checked. If anything here is wrong, tell us at [email protected] and we will correct it.
We use cookies for analytics (Google Analytics) and advertising (Google AdSense) to improve your experience and support free content. Privacy Policy