406 Not Acceptable

Unsatisfiable content negotiation preferences from the client produce the 406 Not Acceptable status code. The resource exists but the server has no representation matching the requested format, language, or encoding.

Usage

When a 406 Not Acceptable error arrives, the response is triggered by a negotiation-related header such as Accept or Accept-Language. When the client includes one or more of these headers, the server satisfies the requirements when possible.

The most common HTTP Accept headers are:

  • Accept: Specifies the preferred content type. A server supplies either plain text or an HTML representation. In this example, the client prefers HTML but accepts plain text.

    Accept: text/html, text/plain
    
  • Accept-Encoding: Specifies encodings the client accepts. In this example, the client indicates support for gzip Compression.

    Accept-Encoding: gzip
    

In practice, this error is rarely used because the server supplies a default representation instead. The rationale assumes the client prefers something over nothing. When the 406 Not Acceptable response is returned, the message body contains a list of available representations the client selects from.

Note

406 Not Acceptable means the server cannot produce a response matching the client's Accept headers (output format problem). 415 Unsupported Media Type means the server does not understand the Content-Type of the request body (input format problem). 406 is about what the client wants to receive while 415 is about what the client sent.

SEO impact

Search engines like Google do not index a URL returning a 406 Not Acceptable status. Previously indexed URLs returning this status code are removed from search results.

Example

The client requests a resource in French, but the server responds with 406 Not Acceptable because only German and English versions are available.

Request

GET /news HTTP/1.1
Host: www.example.re
Accept-Language: fr

Response

HTTP/1.1 406 Not Acceptable
Content-Type: text/html
Content-Length: 242

<html>
  <head>
    <title>French Language Not Available</title>
  </head>
  <body>
    <p>Please choose a supported language:</p>
    <p><a href="/news/news-de.html">German</a></p>
    <p><a href="/news/news-en.html">English</a></p>
  </body>
</html>

How to fix

A 406 Not Acceptable means the server has no representation matching the client's content negotiation headers.

  1. Review the Accept header. Broaden the accepted media types. For example, add application/json alongside text/html, or use */* to accept any format. Use browser DevTools (Network tab) or curl -v to inspect the exact Accept header the client sends.

  2. Check Accept-Language constraints. Requesting a language the server does not support triggers this error. Widen the language list or add a wildcard (*) fallback. Browser language settings control this header automatically. Adjust them in the browser's language preferences.

  3. Remove overly restrictive Accept-Encoding or Accept-Charset values. A narrow encoding or charset requirement limits the server's options. Allow common values like gzip, deflate and UTF-8.

  4. Inspect the response body for available alternatives. The server often lists supported representations in the 406 response. Select one and adjust the negotiation headers accordingly.

  5. Check server-side content negotiation configuration. Misconfigured type maps or missing MIME type registrations on the server cause unexpected 406 responses. In Apache, mod_negotiation and MultiViews control type maps. Verify the AddType directives register the required MIME types.

  6. Check mod_security or WAF rules. Apache's mod_security (and similar WAFs) intercepts requests and returns 406 when a rule triggers on the request content, not the Accept header. Check the server error log for a ModSecurity entry and note the rule ID (e.g., [id "941160"]). Allowlist the specific rule rather than disabling the WAF entirely:

    SecRuleRemoveById 941160
    

    Place the exclusion in the virtual host config or .htaccess file.

  7. Test with a minimal request. Strip all negotiation headers and send a bare request with curl to determine whether the server returns a default representation. If the bare request succeeds, add negotiation headers back one at a time to isolate which header triggers the rejection.

  8. Verify API version negotiation. Some APIs use the Accept header for versioning (e.g., application/vnd.api.v2+json). Sending an unsupported version string produces 406. Confirm the version value against the API documentation.

Code references

.NET

HttpStatusCode.NotAcceptable

Rust

http::StatusCode::NOT_ACCEPTABLE

Rails

:not_acceptable

Go

http.StatusNotAcceptable

Symfony

Response::HTTP_NOT_ACCEPTABLE

Python3.5+

http.HTTPStatus.NOT_ACCEPTABLE

Java

java.net.HttpURLConnection.HTTP_NOT_ACCEPTABLE

Apache HttpComponents Core

org.apache.hc.core5.http.HttpStatus.SC_NOT_ACCEPTABLE

Angular

@angular/common/http/HttpStatusCode.NotAcceptable

See also

Last updated: April 4, 2026