Перейти к основному содержимому

Руководства / Коды состояния HTTP: разбор

400 Bad Request: что означает и как исправить

400 Bad Request означает, что сервер вообще не смог разобрать запрос, еще до того, как перешел к решению, разрешать его или нет. Это делает 400 на шаг раньше, чем ошибки вроде 401 или 403, которые означают, что сервер прекрасно понял запрос и затем отказал по причине политики.

Что означает 400 Bad Request

Согласно RFC 9110, 400 - это способ сервера сказать, что запрос не удалось понять из-за некорректного синтаксиса. Ключевое слово здесь - синтаксис: сервер не оценивает, кто вы, что вам разрешено делать или существует ли ресурс. Он говорит, что сам запрос как последовательность байтов не разбирается как корректный HTTP-запрос. Это может быть стартовая строка запроса, заголовки или тело - в зависимости от того, на чем парсер сдался.

Как выглядит ошибка

Браузеры отображают ту простую страницу ошибки, которую вернул сервер для 400; специальной страницы на уровне браузера, как для сбоя DNS или сертификата, здесь нет, поскольку соединение установилось и ответ действительно пришел. Распространенный вариант дословно гласит "400 Bad Request - request header or cookie too large", что прямо называет причину. Из командной строки:

curl -I https://example.com/some/path
HTTP/1.1 400 Bad Request
Content-Type: text/html

Логи сервера здесь - самое полезное свидетельство, потому что, в отличие от сбоя TLS-рукопожатия, запрос действительно дошел до уровня приложения и логируется, часто вместе с конкретным заголовком или строкой, которую не удалось разобрать.

Что вызывает 400 Bad Request

Для посетителя, в порядке от наиболее вероятного:

  • Слишком большие или поврежденные cookie. Годами накопленные cookie для одного домена, либо cookie, испорченная расширением или неудачным редиректом, регулярно порождает точную формулировку "400 Bad Request - request header or cookie too large", как только общий размер заголовков превышает лимит сервера.
  • Опечатка или неверно закодированный URL. Случайный символ, непреобразованный пробел или сломанная последовательность процентного кодирования в адресной строке или во вставленной ссылке может не пройти как корректный синтаксис.
  • Расширение браузера, изменяющее запросы. Блокировщики рекламы, инструменты приватности и некоторые VPN-расширения переписывают заголовки или стартовую строку запроса, и ошибка в одном из них может отправить серверу нечто некорректное.
  • Закэшированный редирект, указывающий на битый URL. Браузер следует устаревшему редиректу на URL, который сам по себе некорректен, и 400 появляется на странице назначения, а не на той ссылке, по которой вы на самом деле кликнули.
  • Файл загрузки больше, чем разрешает сервер. Некоторые конфигурации сервера отвечают на слишком большую загрузку кодом 400 вместо более точного 413 Payload Too Large.

Для владельца сайта, примерно в порядке того, что стоит проверить в первую очередь:

  • Слишком низкие лимиты на размер заголовков или cookie для того, что приложение на самом деле отправляет, особенно после добавления трекинговых cookie, JWT-токенов в заголовках или механизма сессий, который со временем растет.
  • Некорректный или отсутствующий заголовок Host, который может произвести обратный прокси или неверно настроенный клиент, и который большинству серверов нужен, чтобы вообще маршрутизировать запрос.
  • Content-Length, не совпадающий с реально отправленным телом, что может вызвать сломанный клиент или неисправный промежуточный прокси.
  • Правила web application firewall или ModSecurity, отклоняющие запрос, синтаксис которого выглядит нормально для человека, но совпадает с защитным паттерном, который WAF считает некорректным.
  • API намеренно отклоняет некорректный JSON кодом 400. Это правильное поведение, а не баг: тело запроса, которое не разбирается как валидный JSON, либо не содержит обязательное поле, проверяемое API на уровне синтаксиса, по замыслу должно вернуть 400.

Как понять, кто виноват

Воспроизведите тот же запрос из чистого окружения: приватное окно браузера без расширений и без накопленных cookie, либо простой вызов curl к тому же URL. Если чистый запрос проходит успешно, причина была локальной, чаще всего это cookie или расширение. Если он одинаково падает и из чистого клиента, и откуда-то еще, значит собственные лимиты или правила сервера отклоняют вполне корректно сформированный запрос, и быстрее всего подтвердить это в масштабе, запустив HTTP-проверку из нескольких мест одновременно и сравнив код состояния, который вернулся у каждой.

Как исправить 400 Bad Request

Если вы посетитель

  1. Сначала очистите cookie для сайта, поскольку слишком большие или поврежденные cookie - безусловно самая частая причина. Большинство браузеров позволяют очистить cookie для одного сайта, не сбрасывая все остальные логины.
  2. Повторите попытку в приватном или инкогнито-окне. В чистом окне нет накопленных cookie, и в зависимости от браузера по умолчанию отключено большинство расширений, что изолирует обе распространенные причины одновременно.
  3. Проверьте URL на опечатки или случайные символы, особенно после вставки ссылки, взятой откуда-то, где могли добавить параметры отслеживания или сломать кодирование.
  4. Отключайте расширения по одному, если ошибка сохраняется в обычном окне, но не в приватном режиме, - так вы найдете то расширение, которое переписывает запрос.
  5. Попробуйте другое устройство или сеть, чтобы исключить captive-портал или локальный прокси, вообще не связанный с сайтом.

Если вы администрируете сайт

  1. Повысьте лимиты заголовков и буферов, если приложению они действительно нужны больше. В nginx:
    large_client_header_buffers 4 16k;
    В Apache:
    LimitRequestFieldSize 16384
    В IIS проверьте и maxRequestLength в web.config для тела запроса, и параметр реестра HTTP.sys MaxFieldLength для отдельных полей заголовков.
  2. Сократите то, что вы на самом деле отправляете в cookie и заголовках, а не только поднимайте потолок. Удаление устаревших cookie, вынос крупных токенов из заголовков и более короткое время жизни cookie предотвращают повторение проблемы по мере роста нагрузки.
  3. Проверьте обработку заголовка Host на обратном прокси или балансировщике нагрузки и убедитесь, что он передает приложению корректное, ожидаемое значение.
  4. Прочитайте логи WAF или ModSecurity на предмет конкретного сработавшего правила, если такой инструмент стоит перед приложением; ложное срабатывание требует точечного исключения, а не отключения всего набора правил.
  5. Убедитесь, что 400 от вашего API - это осознанное поведение, прежде чем его "исправлять". Некорректное тело JSON или поле, не проходящее проверку на уровне синтаксиса, должны возвращать 400; правильное решение здесь - более понятные сообщения об ошибке на стороне клиента, а не изменение кода состояния.

400 в сравнении с похожими кодами

  • 401 Unauthorized означает, что запрос был понят нормально, но валидные учетные данные отсутствуют или были отклонены.
  • 403 Forbidden означает, что запрос был понят нормально, но сервер отказывается его авторизовать независимо от учетных данных.
  • 404 Not Found означает, что запрос был понят нормально и ни один ресурс не совпал с путем.
  • 413 Payload Too Large - это конкретный код для тела, превышающего лимит размера, хотя некоторые серверы на практике вместо него отвечают 400.
  • 414 URI Too Long - это конкретный код для стартовой строки запроса, превышающей лимит длины.
  • 422 Unprocessable Content означает, что синтаксис разобрался нормально, а семантика - нет, например валидный JSON со значением, не проходящим бизнес-проверку, - различие тоньше, чем большинство API вообще потрудились сделать по сравнению с 400.

Как не дать ошибке 400 положить страницу

Ошибка 400, вызванная деплоем, ужесточившим лимиты заголовков, или обновлением правила WAF, начавшим совпадать с легитимным трафиком, не проявится как падение или таймаут, поскольку сервер отвечает мгновенно и корректно по своим собственным правилам. Плановая HTTP-проверка с проверкой ожидаемого кода состояния ловит это в тот момент, когда оно начинает происходить, вместо того чтобы ждать, пока накопятся тикеты в поддержку. В сочетании с мониторингом из нескольких мест она также подсказывает, является ли 400 общим для всех или привязан к конфигурации edge-узла одного региона.

Похожие ошибки

Более широкое семейство кодов ошибок клиента и сервера рассмотрено в обзоре кодов 4xx. Смотрите также 403 Forbidden - для запросов, которые сервер понял и отклонил, 404 Not Found - для запросов к несуществующему ресурсу, и 429 Too Many Requests - для запросов, отклоненных из-за частоты, а не синтаксиса.

Часто задаваемые вопросы

Почему очистка cookie исправляет ошибку 400?

Потому что cookie передаются вместе с каждым запросом как заголовки, а сервер применяет максимальный общий размер заголовков. Годами накопленные cookie, либо одна поврежденная cookie, могут вытолкнуть общий объем за этот лимит, и сервер отвечает 400, еще ничего больше не прочитав о запросе.

Одинакова ли ошибка 400 на каждом сайте, который я посещаю?

Код и общая причина - некорректный синтаксис запроса - везде одинаковы, но конкретный превышенный лимит и точная формулировка страницы ошибки задаются собственной конфигурацией сервера каждого сайта.

Должен ли мой API возвращать 400 для некорректного ввода?

Да, когда ввод не разбирается или не содержит поле, которое API проверяет на уровне синтаксиса. Это 400, работающий как задумано, а не баг, который нужно чинить смягчением проверки.

Может ли WAF вызвать ошибку 400 на запросе, который выглядит совершенно нормальным?

Да. Правило WAF может пометить паттерн в URL, заголовке или теле, который технически является валидным HTTP, но совпадает с защитной сигнатурой, и некоторые конфигурации WAF отвечают общим 400 вместо более конкретной страницы блокировки.

В чем разница между 400 и 413?

413 - это конкретный код для тела запроса, превышающего настроенный лимит размера. Многие серверы используют его правильно, но некоторые для того же условия слишком большого тела отвечают 400, поэтому не стоит полагать, что один лишь код точно скажет причину без проверки документации или логов сервера.

Проверить сейчас

Запустите бесплатную проверку своего сайта - аккаунт не нужен.

HTTP check

Следить за этим постоянно

Получайте оповещение в момент сбоя: HostTracker проверяет более чем из 300 локаций и уведомляет по email, SMS, в Slack, Telegram и не только.

Возможности HostTracker

Ещё в этом разделе: Коды состояния HTTP: разбор