HTTPQUERY
Русский

406 Not Acceptable

Применение

Когда приходит ошибка 406 Not Acceptable, ответ вызван заголовком, связанным с согласованием, — например Accept или Accept-Language. Если клиент передаёт один или несколько таких заголовков, сервер по возможности выполняет их требования.

Наиболее распространённые заголовки HTTP Accept:

Accept: задаёт предпочтительный тип содержимого. Сервер предоставляет либо простой текст, либо представление в HTML. В этом примере клиент предпочитает HTML, но принимает и простой текст.

Accept: text/html, text/plain

Accept-Encoding: задаёт кодировки, которые принимает клиент. В этом примере клиент сообщает о поддержке сжатия gzip.

Accept-Encoding: gzip

На практике эта ошибка применяется редко, поскольку сервер вместо неё отдаёт представление по умолчанию. Логика здесь в том, что клиент предпочтёт хоть что-то, чем ничего. Когда ответ 406 Not Acceptable всё же возвращается, тело сообщения содержит список доступных представлений, из которых клиент делает выбор.

Примечание

406 Not Acceptable означает, что сервер не может сформировать ответ, соответствующий заголовкам Accept клиента (проблема формата вывода). 415 Unsupported Media Type означает, что сервер не понимает Content-Type тела запроса (проблема формата ввода). 406 касается того, что клиент хочет получить, а 415 — того, что клиент отправил.

Влияние на SEO

Поисковые системы вроде Google не индексируют URL, возвращающий статус 406 Not Acceptable. Ранее проиндексированные URL, которые начинают возвращать этот код состояния, удаляются из результатов поиска.

Пример

Клиент запрашивает ресурс на французском языке, но сервер отвечает 406 Not Acceptable, поскольку доступны только немецкая и английская версии.

Запрос

GET /news HTTP/1.1
Host: example.com
Accept-Language: fr

Ответ

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>

Как исправить

406 Not Acceptable означает, что у сервера нет представления, соответствующего заголовкам согласования содержимого от клиента.

Пересмотрите заголовок Accept. Расширьте список принимаемых медиатипов. Например, добавьте application/json рядом с text/html или используйте /, чтобы принимать любой формат. Посмотрите точное значение заголовка Accept, отправляемого клиентом, в DevTools браузера (вкладка Network) или через curl -v.

Проверьте ограничения Accept-Language. Запрос языка, который сервер не поддерживает, вызывает эту ошибку. Расширьте список языков или добавьте запасной вариант с подстановочным знаком (*). Этим заголовком автоматически управляют языковые настройки браузера. Измените их в языковых предпочтениях браузера.

Уберите излишне строгие значения Accept-Encoding или Accept-Charset. Узкие требования к кодировке или набору символов ограничивают возможности сервера. Разрешите распространённые значения, такие как gzip, deflate и UTF-8.

Изучите тело ответа на предмет доступных альтернатив. Сервер часто перечисляет поддерживаемые представления в ответе 406. Выберите одно из них и скорректируйте заголовки согласования.

Проверьте конфигурацию согласования содержимого на сервере. Неверно настроенные карты типов или незарегистрированные MIME-типы на сервере приводят к неожиданным ответам 406. В Apache картами типов управляют mod_negotiation и MultiViews. Убедитесь, что директивы AddType регистрируют нужные MIME-типы.

Проверьте правила mod_security или WAF. mod_security в Apache (и подобные WAF) перехватывает запросы и возвращает 406 при срабатывании правила на содержимое запроса, а не на заголовок Accept. Посмотрите в журнале ошибок сервера запись ModSecurity и отметьте идентификатор правила (например, [id “941160”]). Добавьте в список исключений конкретное правило, а не отключайте WAF целиком:

SecRuleRemoveById 941160

Разместите это исключение в конфигурации виртуального хоста или в файле .htaccess.

Протестируйте минимальным запросом. Уберите все заголовки согласования и отправьте «голый» запрос с помощью curl, чтобы выяснить, вернёт ли сервер представление по умолчанию. Если «голый» запрос проходит, добавляйте заголовки согласования обратно по одному, чтобы определить, какой из них вызывает отказ.

Проверьте согласование версии API. Некоторые API используют заголовок Accept для версионирования (например, application/vnd.api.v2+json). Передача неподдерживаемой строки версии приводит к 406. Сверьте значение версии с документацией API.

Примеры кода

.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