406 Not Acceptable

The HTTP 406 Not Acceptable status code is a client error returned by the server to indicate the resource exists but the proactive content negotiation engaged in by the client was not satisfiable, and the server does not supply a default representation.

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.

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

Takeaway

The 406 Not Acceptable status code is a client error returned when the client-specified proactive negotiation requirements are not satisfiable and the server is unwilling to send a default representation.

See also

Last updated: March 6, 2026