X-Content-Type-Options

MIME sniffing allows browsers to override declared content types, creating a security gap. The X-Content-Type-Options response header closes this gap by instructing the browser to respect the declared Content-Type.

Baseline: Widely available

The X-Content-Type-Options header is supported across all major browsers. webstatus.dev

Note

The "X-" naming convention for HTTP headers, "X" referring to "experimental", has been deprecated and needs to be transitioned to the formal naming convention for HTTP headers. Despite the prefix, X-Content-Type-Options is registered in the IANA permanent message headers registry and is part of the Fetch Standard. The prefix reflects its origins before formal standardization.

Usage

MIME sniffing is a browser behavior where the browser inspects the content of a response and overrides the declared Content-Type based on patterns found in the response body. While intended as a convenience for misconfigured servers, MIME sniffing opens a security gap: an attacker uploads a file disguised as an image, the browser sniffs the content as HTML or JavaScript, and a cross-site scripting attack executes.

The X-Content-Type-Options header closes this gap. When set to nosniff, the browser strictly follows the Content-Type header and refuses to load resources where the declared type does not match the expected type. For style destinations, the browser blocks the response unless the Content-Type is text/css. For script destinations, the browser blocks the response unless the Content-Type is a valid JavaScript MIME type.

This header is widely deployed as a standard security hardening measure and is recommended alongside Content-Security-Policy and X-Frame-Options for defense-in-depth.

Values

nosniff

The nosniff value is the only defined value. Setting this directive prevents the browser from MIME-sniffing a response away from the declared Content-Type.

Example

A server delivering a JSON API response with MIME sniffing disabled, ensuring the browser treats the response strictly as JSON:

Content-Type: application/json
X-Content-Type-Options: nosniff

A CSS file served with the correct Content-Type and sniffing protection, preventing the browser from reinterpreting the file:

Content-Type: text/css
X-Content-Type-Options: nosniff

Troubleshooting

Resources blocked by nosniff produce console errors referencing a MIME type mismatch between the declared Content-Type and the expected type for the resource destination.

  1. Script blocked by MIME type mismatch. The browser logs Refused to execute script from '...' because its MIME type ('text/plain') is not executable. This happens when the server sends a JavaScript file with a Content-Type other than a valid JavaScript MIME type (text/javascript, application/javascript). Fix the server configuration. In nginx, confirm include mime.types; appears in the http block. In Apache, verify AddType text/javascript .js exists in the configuration or .htaccess.

  2. CSS not applied due to wrong MIME type with nosniff. The console shows Refused to apply style from '...' because its MIME type ('text/html') is not a supported stylesheet MIME type. The server is sending CSS files as text/html or text/plain instead of text/css. In nginx, adding types { text/css css; } or including the default mime.types file resolves the mismatch. In Apache, add AddType text/css .css to the server configuration.

  3. Server sending wrong Content-Type for static files. Misconfigured servers, CDNs, or object storage (S3, GCS) often serve static files as application/octet-stream or text/plain. Check the Content-Type of each resource using the DevTools Network tab by selecting the request and inspecting the response headers. For S3, set the ContentType metadata on upload. For CDN-served assets, verify the origin returns the correct type since most CDNs pass through the origin's Content-Type unchanged.

  4. Diagnosing blocked resources in DevTools Console. Open the Console tab and filter for MIME-related errors. Each blocked resource message includes the URL, the declared MIME type, and the expected type. Cross-reference with the Network tab: select the blocked request, open the Headers panel, and check the Content-Type response header. The fix is always correcting the Content-Type at the server, not removing the nosniff header.

Configuration

Apply nosniff to all responses. The overhead is negligible and the protection covers scripts, styles, and other subresources.

nginx:

add_header X-Content-Type-Options nosniff always;

Apache:

Header always set X-Content-Type-Options nosniff

IIS (web.config):

<customHeaders>
  <add name="X-Content-Type-Options"
       value="nosniff" />
</customHeaders>

See also

Last updated: April 4, 2026