BuyProxy logo
Log inSign up

HTTP 406Proxy and request errors

406 Not Acceptable: what the error means and how to fix it

Short answer

406 Not Acceptable means the server has the resource but not in any form your request said it would accept. Your client lists the formats and languages it wants in headers such as Accept and Accept-Language; when nothing matches and the server chooses not to send a default, it answers 406. Correcting the request headers usually fixes it.

Defined in RFC 9110, section 15.5.7.

How content negotiation leads to a 406

With each request, a client can say what it is prepared to receive: Accept for media types such as application/json or text/html, Accept-Language for languages and Accept-Encoding for compression. The server picks the best match. RFC 9110 lets a server either ignore preferences it can't meet and send its default, or refuse with 406. Most sites send the default, so 406s are uncommon, and they usually point to a strict API or a filtering rule.

A 406 response should list the formats that are available, though many servers send only a short error message.

What causes a 406 error

  • A strict Accept header. Asking an endpoint that only returns JSON for text/html, or the other way round.
  • A required vendor media type. Some APIs pick their version from Accept, such as application/vnd.example.v2+json, and refuse anything else.
  • An Accept-Language the site has nothing for, on a server set to refuse rather than fall back to a default.
  • A filtering rule set to answer 406. Some web hosts configure their request filtering (ModSecurity rules, for example) to return 406 when a request looks suspicious, so a 406 can be a block.

Did the proxy or the site send the 406?

The site or API. A forward proxy passes your headers through untouched, and inside an HTTPS tunnel it can't read them. Send the same request without the proxy: the same 406 means the proxy isn't involved.

If the response body looks like a hosting or firewall page rather than the API's usual error format, a filtering rule probably sent it.

How to fix a 406 error

  1. Check the API docs for the media type it serves, and send exactly that in Accept.
  2. If any format will do, send Accept: */*, or remove the narrow Accept header your code adds.
  3. Remove or relax Accept-Language if the site may not have your language.
  4. If a filtering rule sent the 406 on your own site, its log names the rule that matched. On someone else's site, contact the owner.

Fix the Accept header: curl and Python

bash
# What the server returns with no format preference
curl -i -H "Accept: */*" https://api.example.com/items

# Ask for the format the API documents
curl -i -H "Accept: application/json" https://api.example.com/items
python
import requests

url = "https://api.example.com/items"
for accept in ("application/json", "*/*"):
    r = requests.get(url, headers={"Accept": accept}, timeout=30)
    print(accept, r.status_code, r.headers.get("Content-Type"))

406 errors when you use proxies

A proxy doesn't change your Accept headers, so a 406 through a proxy is about your request. Changing IPs won't affect it.

What does change with location is which country's site you see, but the language you get still depends on the Accept-Language header you send. If you want the local version of a page, send the local language too; the geo-targeting preview shows the main language of each country you can target. See geo-targeting for what each product can target.

406 Not Acceptable: frequently asked questions

What does a 406 error mean?

Not Acceptable: the server has no version of the resource that matches the formats or languages your request said it would accept.

How do I fix a 406 Not Acceptable error?

Send an Accept header with a format the server provides, such as application/json for most APIs, or */* if any format will do. Relax Accept-Language if the site may not have your language.

What is the difference between 406 and 415?

406 is about the response: the server can't send a format you accept. 415 Unsupported Media Type is about your request body: the server can't read the format you sent.

Why does a site return 406 to my script when the page works in my browser?

Your script probably sends different headers. Browsers send a broad Accept header; a script may send a narrow one, or trip a filtering rule that a browser doesn't. Compare the headers of the two requests.

Testing proxies for a project? There is no free trial period, but support can add 100 MB of free Premium Residential bandwidth to a new account on request, by chat, Discord or email, so you can try your own targets first.

Residential proxies