406 Not Acceptable
4xx client error
The server can't produce a response matching the request's Accept headers.
406 is failed content negotiation. The client said which formats, languages or encodings it accepts (Accept, Accept-Language, Accept-Encoding), and the server has nothing that fits. Most servers ignore an unsatisfiable Accept header and send their default instead, so a 406 usually comes from a strict API framework or a firewall.
| Class | 4xx Client Error |
|---|---|
| Retry? | No — change the request first |
| Cacheable by default | No — only with explicit Cache-Control |
| Response body | Allowed |
| Defined in | RFC 9110 §15.5.7 — 406 Not Acceptable |
Example response
HTTP/1.1 406 Not Acceptable
Content-Type: application/json
Content-Length: 26
{"error":"Not Acceptable"}Common causes
- Requesting
Accept: application/xmlfrom a JSON-only API. - A client library sending an unusually narrow Accept header.
- Some WAFs, notably mod_security, use 406 to block suspicious requests.
How to fix it
- Send
Accept: application/json, or*/*. - On the server, consider falling back to a default representation instead of failing.
- If mod_security sent it, its audit log names the rule that fired.
Send a 406 from your server
Express
res.status(406).json({ error: "Not Acceptable" });Next.js route handler
return Response.json({ error: "Not Acceptable" }, { status: 406 });Flask
return {"error": "Not Acceptable"}, 406Go net/http
http.Error(w, "Not Acceptable", http.StatusNotAcceptable)
nginx
return 406;
Check what a URL returns
Print just the status line from the command line, or check a whole list of URLs at once, with their response headers, in the HTTP Status Checker.
curl -sI https://example.com/your-path | head -n 1
Frequently asked questions
406 vs 415?
406 is about the response format the client will accept (Accept). 415 is about the request format the client sent (Content-Type).
Headers used with 406
Related status codes