MIME Type Reference

Searchable reference for MIME types with extension mapping, RFC sources, and ready-to-paste Nginx, Apache, and Caddy config snippets. Runs entirely in your browser, works offline.

ZERO UPLOAD · ALL LOCAL

Browser MIME enforcement mechanisms

  • MIME sniffing browser inspects response bytes to guess the real type when Content-Type is missing or generic
  • X-Content-Type-Options: nosniff tells the browser to trust the declared Content-Type exactly
  • Cross-origin fonts require Access-Control-Allow-Origin regardless of MIME type — failures are silent
  • Subresource Integrity checks a content hash after the MIME type check passes, not instead of it

Vendor MIME types with the +json suffix

  • JSON:API
  • RFC 9457 HTTP Problem Details
  • RFC 7396 JSON Merge Patch
  • Hypertext Application Language

The +json suffix (RFC 6838) tells a client the underlying representation is JSON regardless of which vendor type it's wrapped in.

Magic byte signatures

  • JPEG FF D8 FF at byte offset 0
  • PNG 89 50 4E 47 0D 0A 1A 0A (8 bytes)
  • PDF ASCII %PDF — bytes 25 50 44 46
  • WebAssembly 00 61 73 6D — a null byte followed by ASCII "asm"

Image formats compared

  • maximum compression, newer browser support, native HDR
  • good compression, broad/near-universal support
  • universal fallbacks

The picture element selects the first source whose type attribute the browser supports — list AVIF first, WebP second, JPEG/PNG last.

Streaming format MIME types

  • application/x-mpegURL
  • video/mp2t
  • application/dash+xml
  • video/mp4; codecs="avc1.42E01E"

iOS Safari enforces HLS MIME types strictly — serving .m3u8 as text/plain or video/mp4 causes the native player to reject the stream with no useful error.

Font formats registered under RFC 8081

  • font/woff2 Brotli compression, universal support since 2016 — the only format worth serving
  • font/woff WOFF 1.0, zlib compression — needed only for IE 11
  • font/ttf, font/otf installation formats, not meant for HTTP delivery
  • Browser support since Chrome 36, Firefox 39, Safari 10, Edge 14

Nginx MIME directives

  • loads the bundled extension-to-type table
  • adds or overrides individual entries, merges with the included file
  • fallback Content-Type for unmatched extensions — usually application/octet-stream
  • nginx -t to check syntax, curl -sI to confirm the served header

A types {} block placed inside a location {} context replaces the parent types table entirely instead of merging with it.

Apache MIME directives

  • AddType AddType mime/type .ext — scope depends on httpd.conf, VirtualHost, Directory, or .htaccess placement
  • TypesConfig sets the path to the global MIME database, typically /etc/mime.types
  • mod_mime must be enabled for AddType/TypesConfig to work — check with apachectl -M | grep mime
  • Validate + reload apachectl -t to check syntax, apachectl graceful to reload without dropping connections

Express MIME patterns

  • accepts extension shortcuts ('json', 'html') or full MIME strings
  • uses the mime-types package, falls back to application/octet-stream for unknown extensions
  • per-file override for formats missing from the bundled mime database
  • has no define() method — no runtime registration on the shared instance

Content-Type must be set before the first response chunk is sent — Express can't rewrite it afterward.

Next.js MIME configuration points

  • headers() in next.config.js overrides Content-Type for static files in /public, evaluated before the static handler
  • NextResponse.json() sets application/json automatically in App Router route handlers
  • Binary responses new Response(buffer, { headers: { 'Content-Type': '...' } })
  • /public directory served by the built-in static handler — route handlers don't apply to it

FastAPI response classes

  • sets Content-Type explicitly — most direct approach
  • infers type via mimetypes.guess_type() — can return None for newer formats
  • requires explicit media_type — no file path to infer from
  • registers a custom mapping for the process lifetime

FileResponse falls back to application/octet-stream when guess_type() can't identify the extension, which triggers a download prompt instead of inline rendering.

How requests sets Content-Type automatically

  • json= serialises the payload and sets application/json
  • data= (dict) sets application/x-www-form-urlencoded
  • data= (bytes/string) sets no Content-Type at all — the server has to guess
  • files= sets multipart/form-data with a generated boundary parameter

Three ways to override Content-Type on Cloudflare

  • new Response(body, { headers: { 'Content-Type': '...' } })
  • dashboard-based Response Header Modification, no code required
  • URL pattern blocks with indented header assignments, applied at deploy time

image/avif and font/woff2 are already compressed internally — Cloudflare correctly excludes them from further Brotli compression.

Deprecated types and their replacements

  • application/javascript, application/ecmascript superseded by text/javascript (RFC 9239)
  • text/xml an alias for application/xml (RFC 7303)
  • image/x-icon replaced by the IANA-registered image/vnd.microsoft.icon
  • application/vnd.ms-fontobject EOT fonts, effectively deprecated with IE end-of-life

Category

APPLICATION (100 types)

application/json
.json
application/xml
.xml .xsl .xslt
application/pdf
.pdf
application/wasm
.wasm
application/javascript
.js .mjs .cjs
application/zip
.zip
application/gzip
.gz .tgz
application/x-tar
.tar
application/x-7z-compressed
.7z
application/vnd.rar
.rar
application/x-bzip2
.bz2
application/vnd.openxmlformats-officedocument.wordprocessingml.document
.docx
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
.xlsx
application/vnd.openxmlformats-officedocument.presentationml.presentation
.pptx
application/msword
.doc
application/vnd.ms-excel
.xls
application/vnd.ms-powerpoint
.ppt
application/octet-stream
.bin .exe .dll
application/x-www-form-urlencoded
application/cbor
.cbor
application/x-protobuf
.proto .pb
application/grpc
application/graphql-response+json
application/vnd.api+json
application/ld+json
.jsonld
application/hal+json
application/jwt
application/manifest+json
.webmanifest
application/rtf
.rtf
application/problem+json
application/json-patch+json
application/merge-patch+json
application/vnd.geo+json
.geojson
application/yaml
.yaml .yml
application/sql
.sql
application/epub+zip
.epub
application/java-archive
.jar
application/vnd.oasis.opendocument.text
.odt
application/vnd.oasis.opendocument.spreadsheet
.ods
application/vnd.oasis.opendocument.presentation
.odp
application/x-ndjson
.ndjson .jsonl
application/vnd.apple.mpegurl
.m3u8
application/dash+xml
.mpd
application/rss+xml
.rss
application/atom+xml
.atom
application/x-apple-diskimage
.dmg
application/x-debian-package
.deb
application/x-rpm
.rpm
application/x-sh
.sh
application/ecmascript
application/toml
.toml
application/zstd
.zst
application/x-xz
.xz
application/x-bzip
.bz
application/x-lzma
.lzma
application/x-iso9660-image
.iso
application/vnd.ms-cab-compressed
.cab
application/vnd.android.package-archive
.apk
application/x-msdownload
.msi
application/vnd.apple.installer+xml
.mpkg
application/x-httpd-cgi
.cgi
application/vnd.google-earth.kml+xml
.kml
application/vnd.google-earth.kmz
.kmz
application/vnd.sqlite3
.sqlite .sqlite3 .db
application/msgpack
.msgpack
application/schema+json
application/wsdl+xml
.wsdl
application/jose+json
application/x-pkcs12
.p12 .pfx
application/pkix-cert
.cer .der
application/x-pem-file
.pem .crt .key
application/pkcs8
.p8
application/pkcs10
.p10 .csr
application/postscript
.ps .eps .ai
application/x-latex
.latex .ltx
application/x-tex
.tex
application/x-dvi
.dvi
application/fits
.fits .fit .fts
application/vnd.oasis.opendocument.graphics
.odg
application/vnd.oasis.opendocument.chart
.odc
application/vnd.oasis.opendocument.formula
.odf
application/vnd.ms-project
.mpp .mpt
application/vnd.visio
.vsd .vst .vss .vsw
application/vnd.ms-access
.mdb
application/vnd.openxmlformats-officedocument.wordprocessingml.template
.dotx
application/vnd.ms-word.document.macroenabled.12
.docm
application/vnd.ms-excel.sheet.macroenabled.12
.xlsm
application/vnd.apple.pages
.pages
application/vnd.apple.numbers
.numbers
application/vnd.apple.keynote
.key
application/typescript
.ts
application/x-perl
.pl .pm
application/x-python-code
.pyc .pyo
application/x-csh
.csh
application/x-troff
.tr .roff .man
application/trig
.trig
application/n-triples
.nt
application/smil+xml
.smil .smi
application/vnd.mozilla.xul+xml
.xul
application/vnd.lotus-1-2-3
.123 .wks

AUDIO (23 types)

audio/mpeg
.mp3 .mpga
audio/ogg
.ogg .oga
audio/wav
.wav
audio/flac
.flac
audio/aac
.aac
audio/opus
.opus
audio/webm
.weba
audio/midi
.mid .midi
audio/mp4
.m4a .m4b .mp4a
audio/3gpp
.3gp .3gpp
audio/aiff
.aif .aiff
audio/x-ms-wma
.wma
audio/amr
.amr
audio/speex
.spx
audio/ac3
.ac3
audio/vorbis
audio/basic
.au .snd
audio/x-caf
.caf
audio/mpegurl
.m3u
audio/vnd.dts
.dts
audio/mp2
.mp2
audio/3gpp2
.3g2
audio/x-realaudio
.ra .ram

FONT (10 types)

font/woff
.woff
font/woff2
.woff2
font/ttf
.ttf
font/otf
.otf
application/vnd.ms-fontobject
.eot
font/collection
.ttc
font/sfnt
.sfnt
application/x-font-truetype
.ttf
application/x-font-opentype
.otf
application/x-font-woff
.woff

IMAGE (35 types)

image/jpeg
.jpg .jpeg .jfif
image/png
.png
image/gif
.gif
image/webp
.webp
image/avif
.avif
image/svg+xml
.svg .svgz
image/vnd.microsoft.icon
.ico
image/x-icon
.ico
image/bmp
.bmp
image/tiff
.tiff .tif
image/heic
.heic
image/heif
.heif
image/apng
.apng
image/jxl
.jxl
image/jp2
.jp2 .j2k .jpf
image/jpx
.jpx
image/vnd.djvu
.djvu .djv
image/vnd.adobe.photoshop
.psd
image/x-portable-bitmap
.pbm
image/x-portable-graymap
.pgm
image/x-portable-pixmap
.ppm
image/x-xcf
.xcf
image/ktx
.ktx
image/ktx2
.ktx2
image/x-exr
.exr
image/x-rgb
.rgb .rgba .sgi
image/x-xbitmap
.xbm
image/x-pcx
.pcx
image/vnd.wap.wbmp
.wbmp
image/x-tga
.tga .tpic
image/vnd.ms-photo
.jxr .hdp .wdp
image/x-win-bitmap
.cur
image/x-emf
.emf
image/wmf
.wmf
image/vnd.radiance
.hdr .rgbe

MODEL (19 types)

model/gltf+json
.gltf
model/gltf-binary
.glb
model/obj
.obj
model/stl
.stl
model/usd
.usd .usda .usdc
model/vnd.collada+xml
.dae
model/vnd.usdz+zip
.usdz
model/mtl
.mtl
model/vnd.dwf
.dwf
model/iges
.igs .iges
model/step
.stp .step .p21
model/step+xml
.stpx .stpxz
model/x3d+xml
.x3d
model/x3d+binary
.x3db .x3dbz
model/x3d-vrml
.x3dv .x3dvz
model/vnd.3mf
.3mf
model/vnd.fbx
.fbx
model/vnd.opengex
.ogex
model/JT
.jt

TEXT (33 types)

text/html
.html .htm
text/css
.css
text/csv
.csv
text/plain
.txt .text .conf .log
text/markdown
.md .markdown
text/calendar
.ics .ical .ifb
text/vcard
.vcf .vcard
text/javascript
.js
text/event-stream
text/tab-separated-values
.tsv
text/xml
.xml
text/x-python
.py .pyw
text/x-java-source
.java
text/x-c
.c .h
text/x-ruby
.rb
text/x-go
.go
text/x-rust
.rs
text/x-kotlin
.kt .kts
text/x-swift
.swift
text/x-scala
.scala .sc
text/x-php
.php .php3 .php4 .php5 .phtml
text/x-diff
.diff .patch
text/uri-list
.uri .urls .uris
text/x-rst
.rst
text/x-asciidoc
.adoc .asciidoc
text/x-nfo
.nfo
text/x-asm
.asm .s
text/troff
.roff .me .ms .mm
text/x-ini
.ini .cfg .inf
text/x-tcl
.tcl .tk
text/x-fortran
.f .f90 .for .f95
text/x-yaml
.yaml .yml
text/cache-manifest
.appcache .manifest

VIDEO (21 types)

video/mp4
.mp4 .m4v
video/webm
.webm
video/ogg
.ogv
video/x-msvideo
.avi
video/quicktime
.mov .qt
video/x-matroska
.mkv .mk3d
video/mp2t
.ts .mts .m2ts
video/mpeg
.mpeg .mpg
video/3gpp
.3gp .3gpp
video/3gpp2
.3g2 .3gp2
video/x-ms-wmv
.wmv
video/x-ms-asf
.asf .asx
video/vnd.avi
.avi
video/iso.segment
.m4s
video/x-dv
.dv .dif
video/x-ms-vob
.vob
video/H264
video/H265
video/AV1
video/x-flv
.flv
video/x-f4v
.f4v

MULTIPART (9 types)

multipart/form-data
multipart/byteranges
multipart/mixed
multipart/alternative
multipart/digest
multipart/related
multipart/signed
multipart/encrypted
multipart/report
No MIME types match your search.
  1. Type a MIME string (e.g. application/json), file extension (e.g. .wasm), or keyword (e.g. "protobuf") to search the database.
  2. Use the category pills (Application, Audio, Font, Image, Model, Text, Video, Multipart) to browse all types in a category.
  3. Click Details on any card to expand the description, spec link, and server configuration snippets in a full-width panel.
  4. Click Copy next to any snippet block to copy the Nginx, Apache, .htaccess, or Caddy directive to your clipboard.

MIME type categories

MIME types are grouped into registered top-level categories such as application, audio, font, image, model, multipart, text, and video, and each one describes a different class of content that a browser or client knows how to interpret.1 The category prefix in a MIME string tells you, at a glance, whether you are dealing with data, media, text, or a composite message.

The two words in play name two different things. The MIME type is the registered media type name itself, the string this database is built from, while Content-Type is the HTTP header field that carries that name on every request and response.2 After the type itself, parameters can ride along, separated by a semicolon, and the most familiar is charset=UTF-8 on text responses, telling the receiver how to decode the bytes that follow the name. When a server or framework asks you to set a content type, the value it expects is the media type string, optionally with a parameter attached.

Media and document types

application/ is the largest category, covering structured data, executables, archives, and API payload formats ranging from JSON and PDF to ZIP archives and WebAssembly. By contrast, audio/ and video/ cover time-based media: audio/mpeg, Opus, AAC, FLAC, and WAV are the most common audio containers, while MP4 with H.264 remains the most compatible web video format and WebM serves as the open alternative.

image/ covers still images and vector graphics, where AVIF and WebP offer the best compression for modern browsers and SVG (image/svg+xml) is the standard for scalable vector artwork. Because the image category spans both raster and vector formats, choosing the right MIME string matters when you are configuring server caching headers or setting up content negotiation for responsive image delivery. Serving an AVIF file as image/jpeg, for instance, gives the browser bytes that contradict the label, and what happens next varies by browser: some sniff the real format and render anyway, while others trust the label or the file extension and can leave the image broken.3

Fonts, models, text, and composites

For downloadable fonts, font/ is the category to check: WOFF2 (font/woff2) is the preferred format because it uses Brotli compression and is supported by all modern browsers,4 while the older EOT format (application/vnd.ms-fontobject) is deprecated. Older registrations like application/font-woff and application/font-sfnt have also been moved into the font/ top-level type under RFC 8081, which reorganized font media types into their own category to avoid mixing them with generic application/ types.5

The remaining categories serve more specialized roles. model/ covers 3D scene and geometry formats such as glTF, GLB, STL, and USDZ, while text/ groups human-readable formats with specific syntax like HTML, CSS, CSV, and Markdown. Finally, multipart/ covers composite messages: multipart/form-data is required for HTML file uploads,6 and multipart/byteranges appears in 206 Partial Content responses.2

The fallback type: application/octet-stream

One entry in the database deserves its own explanation. application/octet-stream declares a body of raw bytes with no claimed format, and it reaches your users through two different doors. When a server has no mapping for a file's extension, it sends the resource as this generic type, which is how most web servers handle unrecognized files.3 On the receiving end, a browser treats the opaque type as unknown binary data and offers a save dialog rather than attempting to render it, because the declared type promises nothing about the bytes it labels.

The two reader goals point in opposite directions. Deliberately serving a file as octet-stream forces a download for any file without mislabeling its real format, a clean way to hand out documents you want saved rather than opened in a tab. Accidentally serving it is the opposite problem: the file that downloads when it should render, the font that never loads, the resource that breaks a page. The fix is not renaming the file but adding its extension's real mapping, and the config snippets in each detail panel are the exact lines to add.

Inside multipart/form-data

An HTML form carrying a file input takes a different shape on the wire. The browser sends it as multipart/form-data with a generated boundary parameter, and every form field and file becomes its own part inside the request body, each part carrying its own headers.6 Inside the same envelope, a plain text field and a 4 MB upload travel as siblings, separated by a delimiter built from the boundary string, which is why the type appears where form submission does and never in a response from a static file server.

That structure explains why you will never find it in a server's types table. multipart/form-data is a request-body structure the browser builds, not a file type a server serves, so no static extension mapping can point at it. Because the boundary value differs per request, generated fresh for each submission, no fixed table entry could match it even if one tried. Servers that accept uploads read the boundary parameter from the request's Content-Type header and split the parts on the delimiter it names, which is the mechanism the whole upload path depends on.

Server configuration

Web servers ship with a built-in MIME type table that covers most common types, but you still need to add explicit configuration when serving newer formats such as WebAssembly, modern image formats like AVIF and WebP, WOFF2 fonts, and 3D assets like glTF. Without those entries, the server falls back to a generic Content-Type and the browser may refuse to handle the file correctly.

MIME reference filtered to image/webp with details showing the .webp extension and Nginx, Apache, .htaccess and Caddy config lines
image/webp maps to the .webp extension. The details panel gives the matching server lines, for example types { image/webp webp; } for Nginx and AddType image/webp .webp for Apache.

Nginx and Apache

In Nginx, you add or override entries with a types block placed inside http {} or server {}, and the snippet format shown in each detail panel is the exact directive to paste into that block.7 In Apache, the equivalent is the AddType directive, which works in httpd.conf, a virtual host config, or a per-directory .htaccess file.8 Both servers merge custom entries with their built-in table, so you only need to declare the types that are missing or that you want to override.

A concrete mapping ties the abstract rule to a real config line. The .wasm extension maps to application/wasm, the type IANA registers for WebAssembly binaries.9 Adding it to an Nginx types block looks like types { application/wasm wasm; } placed inside the http {} or server {} block covering your site. Apache's equivalent is a single line, AddType application/wasm .wasm, dropped into httpd.conf, a virtual host block, or a per-directory .htaccess file.

Caddy

For Caddy v1, the mime directive maps an extension to a MIME type directly inside the Caddyfile, which keeps the rule visible alongside the rest of your site configuration. The snippets shown for Caddy use this exact format,10 so you can paste them in without renaming variables or adjusting paths. Caddy v2 handles MIME types differently through its HTTP app configuration, but the snippets provided here target the v1 directive syntax that many existing deployments still rely on.

Setting the type in application code, then verifying it

The config file is only one layer of the answer. In application code, the response's type is set by a Node handler, a Python route, or a framework's response object, and a fronting proxy can transform it again before it reaches the browser, so whichever layer touches the response last decides the header the visitor sees. Framework code sets the value through its response-header interface, and the string it expects is exactly what the search box above returns: the media type name, with a parameter if the content needs one.

After any change, read what the server actually sends. The Content-Type response header is visible in the browser DevTools Network tab for every request a page makes, and a single request from a terminal or any HTTP client returns the header for one address, which is the whole observation step. A mapping that looks configured can still be overridden downstream, by the framework layer or a proxy, which is why the observation comes after the configuration rather than instead of it. This reference is the lookup for what the header should say: it does not fetch URLs or test servers itself.

MIME Types: Nginx, Apache, and Caddy Configuration

Every file a web server sends carries a Content-Type header, and the server picks it from its own MIME configuration. When that mapping is missing or wrong, browsers refuse scripts, download pages instead of rendering them or block fonts. The guide below lists the types that need explicit configuration, shows how to test headers with curl, covers common misconfigurations and gives the settings for Caddy and for S3 with CloudFront.

Server MIME type configuration controls what Content-Type header every file gets. When a web server delivers a file, the Content-Type response header tells the browser how to handle it: render the content, execute it as a script, or trigger a download. Most servers ship with a built-in MIME type table covering common formats, but newer formats added after the type database was last updated require explicit configuration. AVIF images, WebAssembly modules, and WOFF2 fonts all require manual entries on many server versions.1 Missing or wrong MIME types cause real failures: browsers refuse to execute WebAssembly served without application/wasm, reject cross-origin fonts with incorrect types, and may refuse JavaScript under strict CSP. Testing your configuration with curl before deployment catches mismatches before they reach production users.

Types that need explicit server configuration

Most servers ship with MIME type tables written years before modern formats existed, which means the bundled configuration files that ship with Nginx, Apache, and Caddy reflect the web format landscape of a decade ago rather than today.2 Nginx's bundled mime.types file, Apache's mime.types database, and Caddy's built-in defaults all cover JPEG, PNG, HTML, CSS, and JSON. Yet several widely-used formats are absent from older installs. AVIF images (image/avif) require an explicit entry in Nginx 1.17 and older. WebAssembly files (application/wasm) are missing from most server defaults shipped before 2019. WOFF2 fonts (font/woff2) were absent from Apache's default MIME database until recently.

Strict browser enforcement for modern formats

Furthermore, browser enforcement for these types is strict: application/wasm triggers a hard compile-time error if wrong, while incorrect font MIME types produce silent failures with no browser error message. Building on this, a post-deployment curl audit is the only reliable way to confirm all types are configured correctly. Run curl -sI against representative URLs for each format your server delivers, and compare every Content-Type response header against the expected IANA-registered value. Automating this check in a deployment pipeline catches regressions before they reach production users.

Testing MIME headers with curl

Verifying MIME type headers requires an HTTP response, not a file system check. Run curl -sI https://example.com/assets/app.wasm and read the Content-Type line in the response headers. The -I flag sends a HEAD request, returning only headers without downloading the file body. For local development, run curl -sI http://localhost:3000/path/to/file.avif. Checking several file types in sequence is faster with individual HEAD requests per extension: request one representative file of each format and inspect its Content-Type. Conversely, browser developer tools show Content-Type in the Network panel, but you need a page that actively loads the file, making curl more reliable for systematic auditing. Record the expected and actual Content-Type for each format in a checklist before signing off on a new server configuration.

Common misconfigurations and detection

Three misconfigurations appear across all server types. The first is serving WASM files as application/octet-stream. This happens when the server's MIME table has no application/wasm entry, and the server falls back to its default binary type. Browsers reject this with a hard error. The second is serving AVIF images as application/octet-stream rather than image/avif. The third is serving WOFF2 fonts as application/octet-stream rather than font/woff2. Furthermore, WOFF2 loaded cross-origin requires both the correct MIME type and an Access-Control-Allow-Origin header. Browsers fail silently on incorrect font MIME types: no console error appears, the font simply fails to load and the page uses its CSS fallback. Detecting this requires checking the Network panel for the font request status and Content-Type value.

Caddy v2 MIME type configuration with the header directive

Caddy v2 ships with a built-in MIME type table that covers common formats.3 For newer formats absent from the built-in table, the header directive in a Caddyfile overrides Content-Type on matching responses without touching the global type table. Caddy's named path matchers let you scope each override to requests ending with a specific extension: the declaration @avif { path *.avif } defines a named matcher that a subsequent header directive references.

A complete Caddy override for AVIF and WebAssembly looks like this: define matchers using the @ prefix, then pair each matcher with header @matcher Content-Type "image/avif" or header @matcher Content-Type "application/wasm". Caddy evaluates matchers in the order directives appear in the site block, so place MIME overrides before the file_server directive that serves the static files. This approach changes only Content-Type for matched paths and leaves other response headers untouched.

Caddy's encode directive and already-compressed formats

Caddy's encode directive applies gzip or zstd HTTP compression to responses. It decides which responses to compress based on Content-Type; the default list includes text/html, application/json, and application/javascript. Adding AVIF or WebAssembly overrides with the header directive does not automatically add them to the encode compression list, which is correct behaviour since both formats are already compressed internally. Verify that encode does not apply a second compression pass to these formats by checking that the Content-Encoding header is absent from AVIF and WASM responses after the overrides take effect.

S3 and CloudFront static hosting MIME configuration

Amazon S3 paired with CloudFront is a common static hosting setup where MIME type configuration requires careful attention at the S3 layer, because CloudFront does not independently determine or correct Content-Type values. CloudFront passes the Content-Type header from the S3 origin response directly to the browser without modification, which means the MIME type stored in the object's ContentType metadata field in S3 is exactly what every browser receives on every edge node worldwide. Uploading files without specifying the content type causes S3 to default to application/octet-stream for formats it does not recognise by extension, triggering download prompts instead of inline rendering for images, fonts, and other displayable formats.4

For AVIF images, set the content type to "image/avif" in the S3 upload parameters so that browsers render the image inline instead of triggering a download prompt. For WebAssembly binaries, set the content type to "application/wasm" to avoid the hard compile-time error browsers throw when the type is wrong. Adding these parameters to every upload in your CI pipeline prevents the application/octet-stream fallback from reaching users after each deployment, and it also ensures that any cache invalidation or re-upload during a rollback preserves the correct metadata.

Verifying MIME types on CloudFront distributions

After uploading with correct ContentType metadata, verify the CloudFront distribution by running curl -sI against the CloudFront URL rather than the S3 origin URL directly. CloudFront caches responses; if you previously served an object with the wrong Content-Type, create a CloudFront invalidation for the affected paths before retesting. Create the invalidation with aws cloudfront create-invalidation, passing your distribution ID and the path pattern "*.wasm", then wait for it to complete before running the curl verification.

Remember that the invalidation removes only the cached header value, not the underlying object, so a corrected S3 metadata write must land before the invalidation runs or the edge simply re-caches the wrong type. Ordering the write before the invalidation is the detail most deployments get wrong on the first attempt. CapyToolkit's MIME reference lists the expected Content-Type for every modern format so each curl check has a known target to compare against.

Use this guide when setting up a new static file server, auditing an existing server configuration for MIME type mismatches, or verify server MIME types with curl when your server sends the wrong Content-Type.5

Nginx: add AVIF, WASM, and WOFF2 to the types block

Before
# Without explicit types, these files get application/octet-stream
After
types {
    image/avif  avif;
    application/wasm  wasm;
    font/woff2  woff2;
}

Place inside the http {} or server {} context, after the include mime.types line. These entries add to the built-in table rather than replacing it.

Apache .htaccess: add modern MIME types

Place in .htaccess or httpd.conf. Each AddType line applies to all requests matching that extension.

Caddy: MIME type overrides in Caddyfile

The header directive in Caddy sets response headers for matching requests, including Content-Type overrides.

Sources for this section
  1. 1.

    "application/wasm," IANA, iana.org, accessed June 2026. https://www.iana.org/assignments/media-types/application/wasm

  2. 2.

    Maxim Dounin, "WebAssembly doesn't work on Firefox/Chrome due to missing MIME type," nginx trac ticket #1606, nginx.org, 2021. https://trac.nginx.org/nginx/ticket/1606

  3. 3.

    "Manipulates HTTP response header fields," Caddy docs, caddyserver.com, accessed June 2026. https://caddyserver.com/docs/caddyfile/matchers

  4. 4.

    Amazon Web Services, "PutObject (Amazon S3 API Reference)," docs.aws.amazon.com, accessed October 2026. https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html

  5. 5.

    J. Schaer et al., "HTTP Semantics," RFC 9110, IETF, January 2024. https://www.rfc-editor.org/info/rfc9110/

FAQ

Only in versions shipped after approximately 2021. Older Nginx installs and many Linux distribution packages include a mime.types file that predates WebAssembly's IANA registration. Add "application/wasm wasm;" to your types {} block and run nginx -t to verify the syntax before reloading.

Run curl -sI https://your-domain.com/file.wasm and read the Content-Type header in the output. The -I flag sends a HEAD request so no file data downloads. For local servers, use http://localhost:PORT/path. Repeat for each file extension you care about: .avif, .wasm, .woff2.

Yes. In Nginx, place a types {} block inside a location {} directive matching that path. In Apache, place AddType directives in a .htaccess file in that directory. In Caddy, use a route or path matcher to scope header directives to specific URL patterns.

The browser refuses to compile the module and throws a hard error: "WebAssembly.instantiateStreaming() failed because your server does not serve wasm with application/wasm MIME type." Unlike most MIME type mismatches, this one has no fallback. The module fails to load regardless of the JavaScript error handling you add.

Browsers enforce CORS for cross-origin font requests. A missing Access-Control-Allow-Origin header causes the browser to block the font silently, with no console error. The MIME type must be font/woff2 and the server must also send Access-Control-Allow-Origin: * (or the specific origin) for fonts loaded from a CDN or different domain. CapyToolkit's MIME reference documents both the correct MIME type and the CORS requirements for every font format.

Deprecated types

Several MIME types have been formally superseded or aligned with newer registrations as the web platform has evolved. The most common cases you will encounter are application/javascript and application/ecmascript being replaced by text/javascript under RFC 9239,11 text/xml aligned as an alias for application/xml under RFC 7303,12 and image/x-icon, which Microsoft software itself uses for ICO files even though image/vnd.microsoft.icon is the IANA-registered type.13

EOT fonts (application/vnd.ms-fontobject) are another deprecated family, and every major browser implements WOFF2, so serving EOT adds no value for any modern user agent.4 Deprecated entries in this reference are marked with a yellow warning banner in the detail panel, and each one links to the spec that documents the recommended replacement so you can update your server configuration with confidence and avoid serving stale types to modern browsers.

MIME types and browser security

Browsers treat MIME types as part of their security model. WebAssembly binaries must arrive as application/wasm or the browser refuses to compile them, producing a hard error with no fallback.9 Web fonts loaded from a different origin require a permissive Cross-Origin-Resource-Sharing header, or the browser silently rejects them and the page falls back to system fonts.14 Both restrictions force an explicit guarantee before the browser acts: a matching declared type for WebAssembly, an explicit opt-in from the server hosting the font. Scripts served without a recognized JavaScript MIME type will not execute when the response carries X-Content-Type-Options: nosniff.15

The X-Content-Type-Options: nosniff response header reinforces your declared MIME type. Without it, a browser may detect executable content inside a file and act on that detection regardless of what Content-Type says. Setting nosniff tells the browser to trust your declared type exactly. Combining a correct Content-Type with nosniff closes the gap between what you declare and what the browser assumes. CapyToolkit's server config snippets already include nosniff in the recommended directives for file types where this protection matters most.15

Picked the Right Content Type Checklist

  • WebAssembly served as application/wasm Without this exact type, the browser refuses to compile the module and produces a hard error with no fallback.
  • Modern image formats declared correctly AVIF and WebP need their own MIME types. Serving AVIF as image/jpeg risks a broken image in browsers that trust the label over the bytes.
  • WOFF2 fonts served as font/woff2 The current preferred font format uses Brotli compression and needs the right type to load across modern browsers.
  • X-Content-Type-Options: nosniff set This header stops the browser from guessing a different content type than the one you declared.

Check your own server's response headers against these four before assuming a missing file is a content bug rather than a MIME type.

Sources
  1. 1.

    IANA, "Media Types," iana.org, accessed June 2026. https://www.iana.org/assignments/media-types/media-types.xhtml

  2. 2.

    R. Fielding, M. Nottingham, and J. Reschke, "HTTP Semantics," RFC 9110, IETF, June 2022. https://datatracker.ietf.org/doc/rfc9110/

  3. 3.

    MDN, "Media types (MIME types)," developer.mozilla.org, accessed September 2026. https://developer.mozilla.org/en-US/docs/Web/HTTP/MIME_types

  4. 4.

    W3C, "WOFF File Format 2.0," w3.org, August 2024. https://www.w3.org/TR/WOFF2/

  5. 5.

    C. Lilley, "The font Top-Level Media Type," RFC 8081, IETF, February 2017. https://www.ietf.org/rfc/rfc8081.txt

  6. 6.

    L. Masinter, "Returning Values from Forms: multipart/form-data," RFC 7578, IETF, July 2015. https://datatracker.ietf.org/doc/rfc7578/

  7. 7.

    nginx, "Module ngx_http_core_module: types," nginx.org, accessed June 2026. https://nginx.org/en/docs/http/ngx_http_core_module.html#types

  8. 8.

    Apache Software Foundation, "mod_mime: AddType," httpd.apache.org, accessed June 2026. https://httpd.apache.org/docs/2.4/mod/mod_mime.html#addtype

  9. 9.

    IANA, "application/wasm Media Type," iana.org, accessed June 2026. https://www.iana.org/assignments/media-types/application/wasm

  10. 10.

    Caddy Server, "http.mime," caddy-docs.netlify.app, accessed June 2026. https://caddy-docs.netlify.app/v1/docs/mime

  11. 11.

    M. Miller, M. Borins, M. Bynens, and B. Farias, "Updates to ECMAScript Media Types," RFC 9239, IETF, May 2022. https://www.rfc-editor.org/rfc/rfc9239

  12. 12.

    H. Thompson and C. Lilley, "XML Media Types," RFC 7303, IETF, July 2014. https://www.rfc-editor.org/rfc/rfc7303

  13. 13.

    "ICO (file format)," Wikipedia, accessed September 2026. https://en.wikipedia.org/wiki/ICO_(file_format)

  14. 14.

    W3C, "CSS Fonts Module Level 3," w3.org, September 2018. https://www.w3.org/TR/2018/REC-css-fonts-3-20180920/

  15. 15.

    MDN, "X-Content-Type-Options header," developer.mozilla.org, March 2026. https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Content-Type-Options

FAQ

A MIME type (Multipurpose Internet Mail Extensions type) tells a browser or client what kind of content it is receiving so it knows how to handle it. Without a correct Content-Type header, a browser may refuse to execute a script, render an image incorrectly, or force a download when the file should be displayed inline. Web servers use MIME type configuration to ensure files are served with the right header regardless of how a client requests them.

Both describe JavaScript source code, but application/javascript, application/ecmascript, and related application/* JavaScript types are now historical aliases of text/javascript under RFC 9239. Modern browsers accept the JavaScript media types, but text/javascript is the preferred type to set on your server. A nosniff response header adds another layer, blocking scripts served with a MIME type the browser does not recognize as JavaScript.

MIME type registrations evolve over time. Some types were registered before better alternatives existed. application/javascript was superseded by text/javascript, and application/vnd.ms-fontobject (EOT fonts) by font/woff2. Deprecated types still work in most browsers for compatibility, but serving them signals outdated server configuration. CapyToolkit flags deprecated types with a warning banner so you can identify and update them.

Most servers include built-in MIME type tables that cover common types like image/jpeg, text/html, and text/css out of the box. You typically need to add custom entries for newer formats (image/avif, image/webp, font/woff2), WebAssembly (application/wasm), and 3D formats like model/gltf-binary. The config snippets in the detail panel give you the exact directive to paste into Nginx, Apache, or Caddy.

The impact depends on the type. Serving a web font from a different origin without a permissive Cross-Origin Resource Sharing header makes browsers reject it, and the page falls back to system fonts. Serving WebAssembly without application/wasm blocks instantiation in modern browsers. Serving JavaScript with an incorrect type may prevent execution when the nosniff header is in place. For images and media, browsers are more lenient and often sniff the actual format, but this is not reliable.

Yes. The entire dataset of MIME strings, extensions, RFC references, and config snippets is bundled into the page at build time. Once loaded, search, filtering, and copy functions all run locally in your browser with no network requests.

Additional resources