Hello everyone, welcome back to CybercityHelp. While browsing websites or working with APIs, we often encounter common HTTP errors like 404 or 403. But sometimes, you may see a less familiar response called 406 Not Acceptable, which can feel confusing at first because the request itself looks completely valid.
So in today’s article, we are going to clearly understand what HTTP status code 406 Not Acceptable actually means, how content negotiation leads to this response, what common mistakes trigger it, how you can fix it step by step, and finally how to bypass or avoid this issue real applications. So let’s get started.
What Is HTTP Status Code 406 Not Acceptable?
HTTP status code 406 Not Acceptable means that the server understood your request, the resource exists, but the server cannot provide a response in a format that matches what the client asked for.
This usually happens due to content negotiation, where the client and server fail to agree on response formats like JSON, XML, HTML, or specific character encodings.
How Content Negotiation Causes 406 Not Acceptable?
Content negotiation is the process where the client tells the server what kind of response it expects, and the server decides whether it can fulfill that request.
This information is sent through headers such as Accept, Accept-Language, and Accept-Charset. If the client sends very strict or incorrect values in these headers, the server may not find a compatible response format.
For example, if a client requests only application/xml but the server supports only application/json, the server has no acceptable option to return. In that case, instead of guessing, it correctly responds with 406 Not Acceptable. So the error is not about failure, it’s about incompatibility.
What Are the Common Causes of 406 Not Acceptable Error?
A 406 Not Acceptable error happens when the server understands the request but cannot generate a response that matches what the client asked for in its headers. For example the most common causes are:
1. Strict Accept Header Mismatch
This is the most frequent reason behind a 406 error. The client explicitly requests a response format that the server cannot produce. For example, the client may request XML, while the server only supports JSON responses.
Client request example:
GET /api/users Accept: application/xml
Server supports only:
Content-Type: application/json
Because there is no matching format between the request and the server capability, the server returns 406 Not Acceptable instead of guessing.
2. Browser vs API Response Conflict
Browsers and APIs often expect completely different response formats.
Browsers usually send headers like this:
Accept: text/html,application/xhtml+xml
Most APIs are designed to return:
Content-Type: application/json
If the API is configured strictly and does not allow HTML responses, opening the API endpoint directly in a browser can trigger a 406 error, even though the same endpoint works perfectly in Postman or cURL.
3. Missing or Invalid Content-Type Header
Some servers validate both what the client wants (Accept) and what the client sends (Content-Type). For example, sending JSON data without declaring it properly:
POST /api/login Content-Type: text/plain Accept: application/json
While the server expects:
Content-Type: application/json
Even if the request body looks correct, this mismatch can cause the server to reject the request as unacceptable and return 406 Not Acceptable.
4. Unsupported Language or Character Encoding
Content negotiation also applies to language and character encoding.
Example client request:
Accept-Language: fr-FR Accept-Charset: utf-16
Server supports only:
Accept-Language: en-US Accept-Charset: utf-8
Since the server cannot satisfy the requested language or charset, it responds with 406 Not Acceptable instead of returning incorrect content.
5. Over-Strict Web Server Rules (Nginx / Apache)
Sometimes the application is fine, but the web server blocks the request.
Example Nginx configuration:
location /api/ {
if ($http_accept !~* "application/json") {
return 406;
}
}
This configuration explicitly rejects any request that does not ask for JSON. While secure, such rules can unintentionally block valid clients if headers are slightly different.
6. Framework-Level Content Enforcement
Many frameworks enforce response formats automatically. Spring Boot example:
@GetMapping( value = "/users", produces = MediaType.APPLICATION_JSON_VALUE )
If the client sends:
Accept: text/html
Spring Boot will reject the request and return 406 Not Acceptable because the requested format does not match the declared produces value.
7. Incorrect Headers from Tools (Postman, cURL, Bots)
Testing tools can send unexpected headers. Example cURL request:
curl https://api.example.com/data \ -H "Accept: */*" \ -H "Accept-Encoding: br"
If the server does not support Brotli encoding or wildcard accept rules, it may treat the request as unacceptable and respond with 406, even though the endpoint itself works.
8. CDN or Proxy Header Manipulation
CDNs and proxies can silently modify headers. For example, a CDN may remove or rewrite headers like:
Accept Accept-Encoding Accept-Language
When the backend server receives altered headers, content negotiation may fail, resulting in a 406 Not Acceptable response even though the original client request was valid.
How to Fix 406 Not Acceptable Error Step by Step?
Fixing a 406 Not Acceptable error is not about restarting servers or clearing cache blindly. It is about aligning what the client requests with what the server can actually return. Here’s how to do it properly.
Step 1: Inspect the Accept Header Sent by the Client
The very first thing you must check is the Accept header in the request. A 406 error almost always means the client is asking for a response format the server does not support.
For example, the client may be sending:
Accept: application/xml
While the server only supports:
Content-Type: application/json
In this situation, the fix is simple: either update the client to request a supported format or configure the server to produce the requested format. If you control the client, changing the Accept header to application/json usually resolves the issue immediately.
Step 2: Simplify or Relax the Accept Header
Sometimes the client is too strict. Browsers, bots, or API tools may send very specific headers that unnecessarily limit negotiation. A safer approach during debugging is to allow broader matching.
For example, instead of:
Accept: application/json;version=2
Use:
Accept: application/json
Or temporarily:
Accept: */*
This allows the server to respond with any supported format and helps confirm whether strict negotiation is the root cause.
Step 3: Verify the Content-Type Header for Request Bodies
If the request includes a body (POST, PUT, PATCH), you must ensure the Content-Type header matches what the server expects. For example, a common mistake looks like this:
Content-Type: text/plain Accept: application/json
While the API expects:
Content-Type: application/json
Even if the body contains valid JSON, an incorrect Content-Type can cause the server to reject the request as unacceptable. Always ensure the request payload format and headers align perfectly.
Step 4: Check Framework-Level Response Configuration
Many frameworks enforce response formats strictly. For example, in Spring Boot:
@GetMapping( value = "/users", produces = MediaType.APPLICATION_JSON_VALUE )
If the client sends:
Accept: text/html
Spring will return 406 automatically. To fix this, either update the client headers or allow multiple response types in the controller if appropriate. The same concept applies to Laravel, Django, Express, and other frameworks.
Step 5: Review Web Server Rules (Nginx / Apache)
Sometimes the application is correct, but the web server blocks the request before it reaches the app. Example Nginx rule that causes 406:
if ($http_accept !~* "application/json") {
return 406;
}
If you find rules like this, decide whether they are truly required. Overly strict server-level rules often cause unnecessary 406 errors, especially when browsers or third-party clients are involved.
Step 6: Test the Request Manually Using cURL or Postman
Before changing production code, reproduce the issue manually. Example working request:
curl https://api.example.com/users \ -H "Accept: application/json"
Example failing request:
curl https://api.example.com/users \ -H "Accept: application/xml"
Comparing these side by side makes it very clear which header causes the rejection. This step removes guesswork and prevents accidental misconfiguration.
Step 7: Check CDN, Proxy, or Gateway Header Modifications
If you are using a CDN, reverse proxy, or API gateway, check whether headers are being altered. Some CDNs:
- Remove Accept-Encoding
- Rewrite Accept
- Enforce security-based header filtering
This can break content negotiation even if your backend is correct. Temporarily bypass the CDN or inspect forwarded headers to confirm whether the 406 originates upstream or at the application level.
Step 8: Make the Server More Flexible
If your application serves multiple types of clients, being too strict may not be ideal. Instead of rejecting requests outright, consider:
- Defaulting to JSON when no match is found
- Supporting multiple produces types
- Returning a clear error body explaining supported formats
This doesn’t remove standards, it improves compatibility and reduces unnecessary failures.
Alright, so this was the complete explanation of HTTP 406 Not Acceptable. We discussed what this status code means, how content negotiation leads to it, common mistakes that trigger it, how to fix it step by step, and how you can avoid it in the future.
We hope this article helped you clearly understand why 406 errors happen and how to deal with them confidently instead of guessing. If you still face issues or want a framework-specific guide, feel free to ask in the comment section.
If you want to read more articles related to HTTP errors, APIs, servers, or web development concepts, you can check out our related categories from the top menu bar. So stay connected, and that’s all for today’s article. Thank you so much for reading till the end!
“So keep learning, keep growing!”


