Healthbenefitsofexercise
406 Not acceptable
VPNs

406 Not acceptable

An in-depth guide to understanding, diagnosing, and fixing HTTP 406 Not Acceptable errors.

Henrik Yardley
Henrik Yardley
November 8, 2026 · 7 min read

HTTP 406 Not Acceptable is a client error that happens when a request asks for a response in a format the server cannot provide. The exact message is: the server could not produce a response matching the list of acceptable values defined in the request’s proactive “Accept” headers. In practice, you’ll see a browser or an API client report 406 when the server’s available content types don’t line up with what the client asked for. This guide walks you through what that means, why it happens, and how to fix it.

VPN

What 406 Not Acceptable means in practice

Understanding content negotiation

  • HTTP uses headers like Accept, Accept-Language, Accept-Encoding, and Accept-Charset to negotiate a response.
  • The client sends a list of acceptable formats (for example, text/html, application/json) and sometimes language or encoding preferences.
  • The server should pick a representation that satisfies those preferences. If none can be provided, the server returns 406.

Key distinction from other 4xx and 5xx errors

  • 404 Not Found: resource isn’t there.
  • 403 Forbidden: you can access it, but not in this context.
  • 406 is specifically about not being able to serve a representation that matches the request’s Accept criteria.
  • It’s not necessarily a bug or a broken server. It can be a mismatch between what the client asked for and what the server is configured to produce.

Common causes of 406 errors

Client-side header issues

  • Overly restrictive Accept values: Accept: application/json, application/xml when the server can only do text/plain.
  • Conflicting Accept headers from proxies or middleware that strip or rewrite headers.
  • Incorrect Accept-Language or Accept-Encoding values that the server can’t satisfy.

Server-side configuration and content negotiation

  • A web server (like Nginx or Apache) misconfigured to only serve certain types, ignoring the negotiated type.
  • An application router or API gateway that enforces a strict set of content types and rejects others.
  • Dynamic content negotiation logic in frameworks that isn’t aligned with how the server stores or generates responses.

Proxies, CDNs, and caching layers

  • A caching layer that returns a stored representation with a different Content-Type than the current request’s Accept header suggests.
  • Reverse proxies altering headers, causing the server to think the client requested an unsupported type.

API and microservices patterns

  • An API gateway that routes based on content negotiation but downstream services don’t support the requested format.
  • Versioning or feature flags that change response formats, leading to a mismatch for older clients.

How to diagnose a 406 Not Acceptable

Quick client-side checks

  • Inspect the request headers: Look at Accept, Accept-Language, and Accept-Encoding.
  • Note the server’s response headers: Content-Type, Content-Language, and any Vary headers.
  • Check for proxies: If you’re behind a proxy or CDN, inspect its headers or temporarily bypass to see if the error persists.

Server and app review

  • Verify what representations your app can generate. Do you have HTML, JSON, XML, or other formats?
  • Check the routing or content negotiation logic. Is there a middleware layer that maps Accept values to specific responders?
  • Review server blocks or configuration for default types. Are there fallbacks if a requested type isn’t supported?

Logs and traces

  • Look at server access logs for the request path and headers.
  • Check application logs for errors during content negotiation or when selecting a representation.
  • If possible, enable verbose logging for negotiation code to see why a type was rejected.

Reproducing the issue

  • Try a couple of concrete Accept headers:
  • Accept: text/html
  • Accept: application/json
  • Accept: application/xml
  • Include language and encoding headers to see if those are part of the problem.
  • Attempt the same request from different clients (browser, cURL, Postman) and through caching layers to isolate where the mismatch occurs.

How to fix 406 Not Acceptable

Adjust client requests

  • Simplify Accept header: If you don’t need multiple formats, request a single, supported type, e.g., Accept: application/json.
  • Align expectations: Ensure the server actually supports the requested format. If not, switch to a supported type.
  • Normalize headers: Remove or correct conflicting headers introduced by libraries or proxies.

Update server and application logic

  • Expand content negotiation: Ensure the app can generate the formats you claim to support. Implement a robust negotiation path that gracefully handles unsupported Accept values.
  • Provide explicit fallbacks: If a requested type isn’t available, consider returning a 406 with a helpful message, or better yet, return a 200 with a default representation.
  • Align routes with representations: If a route should only serve JSON, enforce that in the route handler and return 406 for other Accept values with a clear message.

Review server configuration

  • Web server config: Ensure the server is not configured to force a single Content-Type or to drop negotiations in certain contexts.
  • Proxy and CDN rules: Check for header rewrites that could misrepresent Accept or Content-Type headers. Disable or adjust rules that cause mismatches.
  • Cache strategies: If using a cache, ensure the stored response Content-Type matches what the client expects for that request.

Implement helpful error responses

  • Add a 406 body that explains why the request was rejected and what formats are supported.
  • Include a helpful link to documentation or a contact page so clients know how to request an acceptable format in the future.
  • Return compatible variations: If possible, offer a default format (like JSON) when the Accept header is too restrictive.

Security and compatibility considerations

  • Do not leak internal server details in 406 responses. Keep messages user-friendly and non-sensitive.
  • Ensure that error handling doesn’t create information leakage that could aid attackers.
  • Keep backward compatibility when introducing new content types or deprecating old ones.

A practical comparison: when to expect 406 vs other errors

Situation Likely error What to check
Client requests a format the server truly cannot produce 406 Not Acceptable Inspect Accept header and available representations on the server
Server can produce multiple formats, but middleware blocks some 406 Not Acceptable Review negotiation pipeline and middleware rules
Client requests a non-existent resource or wrong path 404 Not Found Verify path and routing, not Accept headers
Client is authenticated but requests forbidden formats 403 Forbidden Check authorization logic and content negotiation guardrails
Server misconfig or proxy alters headers 406 Not Acceptable or 500 Check proxies/CDNs and server blocks, test in isolation

Common scenarios with practical fixes

  • Scenario: A REST API only returns JSON, but a client sends Accept: application/xml.

  • Fix: Ensure the API documents that JSON is supported and either respond with 406 with a clear message or simply return JSON with Content-Type: application/json if you want to keep a friendly fallback.

  • Scenario: A web app serves HTML and JSON, but a CDN is caching only HTML.

  • Fix: Configure the CDN to respect Vary: Accept headers or to cache separate variants for Accept: text/html and Accept: application/json.

  • Scenario: A mobile app requests a rarely used encoding, like br (Brotli), and the server doesn’t support it in certain routes. Free VPN for Edge

  • Fix: Either enable brotli for those routes or ensure clients gracefully fall back to gzip or identity encoding.

  • Scenario: A client behind a proxy changes Accept-Language in a way that the server can’t satisfy.

  • Fix: Validate and preserve the original client’s Accept-Language, or implement a neutral default language when a perfect match isn’t available.

Final recommendations

  • Start with the client: verify the exact Accept headers and simplify them to a supported single type if you’re debugging.
  • Inspect the server’s capabilities: list the response formats your application can produce and verify the negotiation path.
  • Check infrastructure boundaries: proxies, CDNs, and load balancers can introduce subtle negotiation issues. Test end-to-end with and without these components.
  • Improve error messaging: when a 406 occurs, return a clear, actionable response that tells the client which formats are supported and how to request them.
  • Document supported formats: keep an up-to-date README or API docs listing exactly which Representations (HTML, JSON, XML, etc.) are available for each route.

If you’re troubleshooting a 406 Not Acceptable issue, approach it in layers: client headers first, then server negotiation logic, then infrastructure (proxies and caching). A well-structured approach reduces the time to a clean fix and prevents similar errors in the future.

© Healthbenefitsofexercise 2026