MIME type lookup · Guide
How to Find a File’s MIME Type: Extension, Header and Content Detection
You can find a file's MIME type from its extension, an HTTP `Content-Type` header, browser metadata or its bytes. Those methods answer different questions: extension lookup predicts the conventional type, a response header states how a server labels content, and byte inspection estimates what a local file contains. For display or configuration a lookup is enough; for an untrusted upload, compare several signals and validate the complete format.
Look up the extension when you need the conventional type
An extension-to-MIME table is appropriate when configuring a web server or identifying the expected type for a known asset. .pdf conventionally maps to application/pdf, .png to image/png, and .json to application/json.
Extension MIME type
.html text/html
.css text/css
.js text/javascript
.json application/json
.svg image/svg+xml
.pdf application/pdfA lookup does not inspect the file. Renaming payload.html to photo.jpg changes the extension but not the bytes. Multiple extensions can share one MIME type, and one extension may have platform-specific or legacy mappings.
Normalise an input extension by removing a leading dot and comparing case-insensitively. Do not take everything after a user-supplied path without first isolating a safe filename; query strings and directory components are not part of the extension.
Read the HTTP Content-Type for remote resources
For a URL, inspect response headers. A HEAD request is efficient when the server implements it correctly; otherwise request the resource while avoiding unnecessary output. Redirects can lead to a different resource, so follow them deliberately and inspect the final response.
curl -I -L https://example.com/manual.pdf
HTTP/2 200
content-type: application/pdf
content-length: 482193The header is the server's declaration, not independent detection. A misconfigured origin may serve every unknown extension as text/plain or application/octet-stream. application/octet-stream means arbitrary binary bytes and often prompts download; it does not identify the underlying format.
Parameters refine a media type. text/html; charset=utf-8 has the base MIME type text/html and a character-set parameter. Preserve parameters for HTTP behaviour, but remove them before comparing with a bare media-type allow-list.
Inspect local bytes with file and libmagic
On Unix-like systems, file uses a magic database to inspect signatures and other patterns. Ask for only the MIME type when scripting so descriptive text and character-set details do not complicate the result.
file --mime-type --brief report.pdf
# application/pdf
file --mime --brief data.csv
# text/csv; charset=us-asciiDetection is probabilistic. Plain-text formats overlap, small or empty files lack enough evidence, and polyglot files can satisfy more than one parser. The installed magic database version can also change the reported label.
Use byte detection as a strong clue, not as proof that a file is safe or structurally complete. If the application will process an image, archive or document, open it with the same kind of maintained parser that will consume it and reject parse failures.
Detect MIME types in PHP and Python
PHP's Fileinfo extension exposes libmagic through finfo. Pass the actual temporary-file path, not the original filename or client-declared upload type.
$finfo = new finfo(FILEINFO_MIME_TYPE);
$type = $finfo->file('/path/to/upload.tmp');
if ($type === false) {
throw new RuntimeException('Could not inspect file');
}
echo $type; // for example image/pngPython's standard mimetypes module performs extension lookup; it does not inspect bytes. That makes it useful for constructing headers for trusted files, but insufficient for validating uploads.
import mimetypes
type_, encoding = mimetypes.guess_type('archive.tar.gz')
print(type_) # application/x-tar on common installations
print(encoding) # gzip
# Results come from filename and platform mappings, not file contents.Be clear in function names: mime_from_extension and detect_mime_from_bytes should not be interchangeable. Callers can then choose based on whether they possess a trusted name, a local file or an untrusted upload.
Understand browser file metadata
A browser File object exposes type, normally inferred from the local filename or operating-system mapping. It may be an empty string, and a custom HTTP client can declare anything. Use it for immediate user feedback, never as the server's sole security check.
input.addEventListener('change', () => {
const file = input.files[0];
console.log(file.name); // photo.png
console.log(file.type); // image/png, or possibly ''
console.log(file.size); // bytes
});The accept attribute filters the file chooser but does not validate the selected bytes. Drag-and-drop and crafted requests can bypass it. Repeat size, type and format checks on the server.
Fetching a remote file exposes its server-declared response type through response.headers.get('content-type'); browser CORS rules may prevent scripts from reading cross-origin responses or non-safelisted headers.
Resolve disagreements between extension and content
A disagreement is information. For trusted assets it may indicate a wrong server mapping or a filename mistake. For uploads it may be suspicious. Do not quietly choose whichever signal makes the file acceptable.
name: avatar.jpg
client type: image/jpeg
detected: text/html
result: reject; do not rename or serve inline
name: no-extension
detected: image/png
result: policy decision after successful image decodeFor an allowed upload, map the successfully detected and parsed format to a server-selected extension and MIME type. Generate a random storage name rather than preserving double extensions or path characters from the original name.
Some legitimate formats are containers: modern office documents are ZIP-based, and a generic detector may report application/zip. Format-specific inspection of internal entries is needed when distinguishing them matters.
Set Content-Type without enabling sniffing
Once the type is known, set Content-Type from trusted metadata. Browsers use it to choose parsing and rendering behaviour. For untrusted downloads, also prevent MIME sniffing and use attachment disposition when inline display is unnecessary.
HTTP/1.1 200 OK
Content-Type: application/pdf
Content-Disposition: attachment; filename="manual.pdf"
X-Content-Type-Options: nosniff
...bytes...nosniff tells browsers not to reinterpret a response as executable script or style when the declared type is wrong. It does not repair an incorrect header; configure the accurate type and use the header as defence in depth.
A useful workflow therefore depends on the question: look up an extension to configure expected behaviour, inspect headers to debug a server, detect bytes to classify a local file, and parse the full format when accepting untrusted content.
Frequently asked questions
How do I find a file's MIME type?
For a trusted filename, look up its extension. For a local file, inspect bytes with file --mime-type, PHP Fileinfo or a libmagic binding. For a remote URL, inspect its final HTTP Content-Type header.
Can a MIME type be determined from the extension?
An extension gives the conventional expected type but does not inspect content. It is suitable for known assets and configuration, not proof that an untrusted file actually has that format.
What does application/octet-stream mean?
It is the generic media type for arbitrary binary data. It normally indicates that the sender cannot or will not identify a more specific format, and it should not bypass an upload allow-list.
Why is a file's MIME type empty in JavaScript?
Browser File.type depends on local filename and platform mappings, so unknown or extensionless files may return an empty string. The server must inspect the uploaded bytes and enforce its own policy.
Can the Content-Type HTTP header be wrong?
Yes. It is configured by the server and may be generic or mistaken. Compare it with the expected extension and actual bytes when debugging, and correct the origin configuration rather than relying on browser sniffing.
Is detecting magic bytes enough for upload security?
No. Signatures identify many formats but do not prove the entire file is valid, harmless or non-polyglot. Use a narrow allow-list and parse or decode the complete format before accepting sensitive uploads.
Ready to try it?
Open the free browser-based MIME type lookup and apply what you just read — no sign-up, runs locally.
Open the MIME type lookup tool