
Ошибка 400 (Bad Request) — это ответ сервера «запрос составлен неверно, обрабатывать не буду». Код ошибки 400 относится к клиентским: сервер работает, но не может разобрать то, что прислал браузер или программа. У посетителей сайта причина чаще всего в раздутых или повреждённых cookie, у разработчиков — в битом JSON, неверных заголовках и слишком больших заголовках запроса.
Что значит ошибка 400 Bad Request
Код 400 Bad Request относится к классу клиентских ошибок 4xx. Согласно RFC 9110, §15.5.1, сервер возвращает 400, когда «не может или не будет обрабатывать запрос из-за чего-то, что воспринимается как ошибка клиента» — например, искажённый синтаксис, недействительное обрамление сообщения или обманчивая маршрутизация запроса.
Ключевое слово здесь — «клиентская». В отличие от ошибок 5xx, где виноват сервер, при 400 сервер сообщает: «Я работаю нормально, но твой запрос собран неправильно». Поэтому первый шаг диагностики — понять, что именно в запросе не так.
Код 400 — самый общий в своём классе. Стандарт разрешает возвращать его всякий раз, когда нет более точного кода, поэтому одна и та же цифра в разных программах описывает очень разные проблемы: от лишнего пробела в адресе до отсутствующего поля в API-запросе. Отсюда и формулировки, в которых его ищут: «400 ошибка запроса», «ошибка HTTP-запроса, код ошибки 400», «ошибка сервиса 400». Суть везде одна — запрос дошёл до сервера и был отклонён ещё до того, как сервер начал выполнять саму операцию.
Как выглядит ответ 400
HTTP/1.1 400 Bad Request
Content-Type: text/html; charset=utf-8
Connection: close
<html>
<head><title>400 Bad Request</title></head>
<body><h1>Bad Request</h1></body>
</html>
Текст ошибки 400 зависит от того, кто её отдал. Самые частые варианты, которые видит пользователь:
| Текст на странице | Кто отдаёт | Что это значит |
|---|---|---|
400 Bad Request — Request Header Or Cookie Too Large | nginx | Заголовки или cookie не поместились в буфер сервера |
400 Bad Request — The plain HTTP request was sent to HTTPS port | nginx | На HTTPS-порт пришёл обычный HTTP-запрос |
400 No required SSL certificate was sent | nginx | Сервер требует клиентский сертификат (mTLS), а его нет |
Size of a request header field exceeds server limit | Apache | Одно поле заголовка длиннее LimitRequestFieldSize |
HTTP Error 400. The size of the request headers is too long. | IIS / HTTP.sys | Суммарный размер заголовков превысил лимит Windows-сервера |
Request failed with status code 400 | axios (JavaScript) | API отклонил запрос; подробности — в теле ответа |
400 Client Error: Bad Request for url: … | Python requests | То же самое, текст формирует raise_for_status() |
Причины ошибки 400: клиент и сервер
Хотя формально 400 — всегда «вина» клиента, спровоцировать её может и конфигурация сервера (например, слишком строгие лимиты на размер заголовков). Ниже — сводная таблица типичных причин.
| Причина | Сторона | Что происходит | Как исправить |
|---|---|---|---|
| Испорченные или слишком большие cookie | Клиент | Браузер шлёт устаревшие/битые cookie, размер заголовка превышает лимит | Очистить cookie сайта |
| Битый синтаксис запроса | Клиент | Некорректная строка запроса, лишние символы, нарушено обрамление | Проверить формирование запроса в коде |
| Слишком длинный URL или заголовки | Клиент + Сервер | Длина URL/заголовков превышает лимит сервера | Сократить URL, увеличить буферы nginx |
| Неверный Content-Type / битый JSON | Клиент | Тело не соответствует заявленному типу, ошибка в JSON | Валидировать JSON, выставить верный заголовок |
| Устаревший кэш браузера | Клиент | Кэш хранит несовместимые данные запроса | Очистить кэш, обновить страницу |
| Строгие лимиты заголовков | Сервер | large_client_header_buffers слишком мал | Поднять лимиты в конфиге |
| Незакодированные символы в URL | Клиент | Пробел, кириллица или одиночный % в адресе без URL-кодирования | Кодировать параметры (encodeURIComponent, urllib.parse.quote) |
| Нет заголовка Host или их два | Клиент / прокси | Запрос HTTP/1.1 без Host обязан получить 400 | Исправить клиент или прокси, формирующий запрос |
| HTTP на HTTPS-порт | Клиент + Сервер | Обращение http://site:443 или прокси шлёт открытый HTTP на порт TLS | Исправить схему в адресе или в proxy_pass |
Про заголовок Host правило жёсткое: RFC 9112, §3.2 требует от сервера ответить 400 на любой запрос HTTP/1.1, в котором заголовка Host нет или он повторяется. Это частая причина 400 у самописных клиентов и неверно настроенных балансировщиков.
Испорченные cookie — причина №1
Самая частая причина 400 у обычных пользователей — «раздувшиеся» или повреждённые cookie. Когда сумма cookie превышает лимит буфера сервера (обычно 4–8 КБ), сервер обрывает запрос с кодом 400. Симптом: ошибка появляется только на одном сайте, а в режиме инкогнито сайт открывается нормально.
Request Header Or Cookie Too Large: слишком большие заголовки
Сообщение 400 Bad Request — Request Header Or Cookie Too Large отдаёт nginx, когда хотя бы одна строка заголовка не помещается в буфер large_client_header_buffers. По умолчанию это 4 буфера по 8 КБ, и одна строка заголовка должна уместиться в один буфер целиком. Все cookie сайта браузер отправляет одной строкой Cookie:, поэтому их суммарный объём и упирается в этот предел.
Кто обычно раздувает заголовки:
- системы аналитики и A/B-тестов, которые пишут по нескольку cookie на каждый визит;
- авторизация через SSO/OAuth, хранящая длинный JWT прямо в cookie;
- поддомены, выставляющие cookie на весь домен (
Domain=.example.com), — браузер отправляет их на каждый поддомен; - прокси и балансировщики, дописывающие свои заголовки (
X-Forwarded-Forс длинной цепочкой адресов).
Стоит помнить и про код 431 Request Header Fields Too Large из RFC 6585: он создан ровно для этой ситуации, но nginx по историческим причинам отвечает 400. Поэтому 400 и 431 для слишком больших заголовков — одна и та же проблема, просто разные серверы называют её по-разному. А вот слишком длинная строка запроса (сам URL) в nginx и Apache обычно даёт уже 414 URI Too Long, а не 400.
Битый JSON и неверный Content-Type
При работе с API 400 часто вызывает некорректное тело запроса. Если вы объявили Content-Type: application/json, но прислали невалидный JSON, сервер ответит 400.
POST /api/v1/orders HTTP/1.1
Host: example.com
Content-Type: application/json
{ "name": "Иван", "amount": } <-- после двоеточия нет значения
400 ошибка запроса в API: «Request failed with status code 400»
Фраза Request failed with status code 400 — это не текст сервера, а стандартное сообщение библиотеки axios в JavaScript. Оно говорит лишь, что сервер вернул 400; причина лежит в теле ответа, которое axios по умолчанию не выводит. Первое, что нужно сделать, — распечатать его:
try {
await axios.post('https://api.example.com/v1/orders', payload);
} catch (err) {
if (err.response) {
console.log(err.response.status); // 400
console.log(err.response.data); // описание ошибки от API
}
}
У fetch другое поведение: он не бросает исключение на 400, поэтому ответ нужно проверять вручную через response.ok и читать тело через await response.json() или await response.text(). В Python библиотека requests превращает 400 в исключение только после вызова raise_for_status(), а текст ответа доступен в response.text.
Почти всегда тело ответа сразу называет причину. Типичные ошибки API-запроса с кодом 400:
- не передан обязательный параметр или он назван иначе, чем в документации (
user_idвместоuserId); - неверный тип значения: строка вместо числа, число вместо массива, дата не в том формате;
- тело отправлено не в том формате: сервер ждёт JSON, а клиент шлёт
application/x-www-form-urlencodedили наоборот; - JSON закодирован дважды — вместо объекта уходит строка с экранированными кавычками;
- лишние символы в начале тела, например BOM в файле, из которого читается JSON;
- превышены ограничения самого сервиса — слишком длинный текст, слишком много элементов в пакете.
Это же касается готовых сервисов: если «ошибка сервиса 400» или «ошибка отправки 400» появляется в облачной программе, документообороте или нейросетевом API, сервис отклонил запрос из-за его содержимого. Пользователю стоит обновить страницу, выйти и войти заново, очистить cookie этого сервиса и повторить операцию; если ошибка повторяется на одних и тех же данных, нужен полный текст ошибки для поддержки сервиса. Для интеграций правило то же, что и выше: читать тело ответа, а не только код.
Как исправить ошибку 400 пользователю
Если вы столкнулись с 400 как посетитель сайта, по порядку попробуйте:
- Очистите cookie этого сайта — в настройках браузера удалите данные конкретного домена.
- Очистите кэш и перезагрузите страницу (Ctrl+F5 / Cmd+Shift+R).
- Проверьте URL — уберите лишние символы, обрежьте слишком длинную ссылку.
- Откройте сайт в режиме инкогнито — если работает, проблема в cookie/кэше основного профиля.
- Отключите расширения, которые могут вмешиваться в запросы.
Удалять стоит данные только проблемного сайта, а не всего браузера — иначе придётся заново входить на все сайты:
- Chrome, Яндекс Браузер, Edge: нажмите значок слева от адреса сайта, откройте раздел о файлах cookie и данных сайта и удалите их для этого домена. Полный список лежит в настройках, в разделе конфиденциальности, в пункте о данных сайтов.
- Firefox: значок замка слева от адреса → «Удалить куки и данные сайта».
- Safari: «Настройки» → «Конфиденциальность» → «Управлять данными веб-сайтов» → найти домен → «Удалить».
Если ссылку вам прислали в мессенджере или письме, откройте её не целиком, а только главную страницу сайта: длинные ссылки с метками и параметрами иногда обрезаются или ломаются при копировании. Если же 400 появляется сразу на многих сайтах, причина скорее в расширении, антивирусе с проверкой HTTPS-трафика или корпоративном прокси, чем в cookie.
Как исправить ошибку 400 разработчику
Если 400 отдаёт ваш сервер, проверьте формирование запроса и лимиты. При отправке JSON всегда валидируйте тело и выставляйте корректный заголовок:
curl -v -X POST https://example.com/api/v1/orders \
-H "Content-Type: application/json" \
-d '{"name":"Иван","amount":100}'
В Windows 10 и 11 тот же запрос можно отправить встроенным curl.exe или через PowerShell. В PowerShell 7 параметр -SkipHttpErrorCheck не даёт командлету бросить исключение, и ответ с кодом 400 можно разобрать:
$r = Invoke-WebRequest -Uri https://example.com/api/v1/orders -Method Post `
-ContentType 'application/json' -Body '{"name":"Ivan","amount":100}' -SkipHttpErrorCheck
$r.StatusCode
$r.Content
Если ошибка вызвана большими заголовками (например, длинный JWT в cookie или заголовке Authorization), увеличьте буферы в nginx:
http {
client_header_buffer_size 16k;
large_client_header_buffers 4 16k;
}
Для Apache аналогичный лимит задаёт LimitRequestFieldSize (по умолчанию 8190 байт на одно поле заголовка). После правки проверьте конфигурацию (nginx -t или apachectl configtest) и перезагрузите сервер. Поднимать лимиты бесконечно не стоит: огромные заголовки лучше лечить на стороне приложения — хранить в cookie идентификатор сессии, а не весь токен.
Чтобы убедиться, что дело именно в размере заголовков, воспроизведите ошибку искусственно — отправьте запрос с cookie на 20 КБ и посмотрите на код ответа:
curl -s -o /dev/null -w "%{http_code}\n" \
-H "Cookie: test=$(head -c 20000 /dev/zero | tr '\0' 'a')" https://example.com/
Флаг -v в curl показывает и отправленные заголовки запроса, и полученный ответ — это лучший способ увидеть, что реально ушло на сервер.
Что искать в логах сервера
nginx записывает причину 400 в error.log, а не только код в access.log. Смотрите журнал в момент воспроизведения ошибки:
tail -f /var/log/nginx/error.log
grep ' 400 ' /var/log/nginx/access.log | tail -n 20
Характерные строки: client sent too long header line — слишком большой заголовок, client sent invalid request или client sent invalid header line — нарушен синтаксис, client sent plain HTTP request to HTTPS port — перепутаны схема и порт. Подробнее о том, где лежат журналы и как их читать, — в разборе логов nginx.
Как диагностировать источник 400
Чтобы понять, где именно ломается запрос, действуйте от простого к сложному:
- Воспроизведите ошибку в инкогнито — исключите влияние cookie/кэша.
- Повторите запрос через
curl -v— увидите точные заголовки и тело. - Сравните успешный и падающий запрос по заголовкам и телу.
- Проверьте логи сервера — nginx пишет причину (например, «client sent too long header»).
- Если перед сервером стоит CDN или балансировщик, отправьте запрос напрямую на сервер приложения: 400 могла отдать промежуточная прослойка, а не ваш бэкенд. Кто ответил, обычно видно по заголовку
Serverи оформлению страницы ошибки.
400 против других 4xx: не путайте коды
Код 400 — «общий» ответ на некорректный запрос. Но у него есть более конкретные соседи, и если сервер спроектирован грамотно, он вернёт именно их. Понимание разницы ускоряет диагностику.
- 400 Bad Request — синтаксис запроса битый, сервер не может его разобрать в принципе.
- 401 Unauthorized — синтаксис верный, но не хватает учётных данных аутентификации.
- 403 Forbidden — вы аутентифицированы, но прав на ресурс нет.
- 422 Unprocessable Content — синтаксис верный, но данные не проходят бизнес-валидацию (например, email в неверном формате).
| Код | Название | Когда возвращается | Что делать |
|---|---|---|---|
| 400 | Bad Request | Запрос нельзя разобрать или он нарушает правила протокола | Исправить сам запрос, очистить cookie |
| 401 | Unauthorized | Нет учётных данных или они неверны | Войти заново, обновить токен |
| 403 | Forbidden | Доступ запрещён, даже если вы вошли | Проверить права и правила сервера |
| 404 | Not Found | Ресурса по этому адресу нет, причина не сообщается | Проверить адрес, настроить редирект |
| 410 | Gone | Ресурс удалён намеренно и навсегда | Убрать ссылки на адрес |
| 414 | URI Too Long | Строка запроса длиннее лимита сервера | Передавать данные в теле POST |
| 422 | Unprocessable Content | Формат верный, но данные не проходят проверку | Исправить значения полей |
| 431 | Request Header Fields Too Large | Слишком большие заголовки или cookie | Уменьшить заголовки, очистить cookie |
Важный нюанс: некоторые фреймворки отвечают 400 там, где по смыслу подошёл бы 422. Если вы разработчик API, старайтесь разделять «не смог разобрать запрос» (400) и «разобрал, но данные логически некорректны» (422) — это упрощает отладку для клиентов вашего API.
Почему один и тот же запрос падает в одном браузере, но не в другом
Если 400 воспроизводится в Chrome, но не в Firefox или в инкогнито, дело почти всегда в состоянии, привязанном к профилю: накопленные cookie, расширения, переписывающие заголовки, или сохранённый в кэше устаревший запрос. Браузеры хранят cookie независимо, поэтому «раздутый» набор в одном профиле легко превышает буфер сервера, тогда как чистый профиль укладывается в лимит. Это же объясняет, почему очистка данных конкретного сайта — самое быстрое лечение.
Ошибка 410 Gone и её отличие от 404
Код 410 Gone — ближайший родственник 404, но смысл у них разный. По RFC 9110, §15.5.11 ответ 410 означает, что ресурс удалён намеренно, больше не появится и ссылки на него стоит убрать. 404 ничего не обещает: страницы нет сейчас, но причина неизвестна, и она может вернуться.
На практике 410 отдают для страниц, которые убрали окончательно: снятые с продажи товары без замены, закрытые акции, удалённые по запросу материалы. Поисковые роботы исключают такие адреса из индекса так же, как 404, но 410 явно сообщает, что возвращаться за страницей незачем. Если у удалённой страницы есть актуальная замена, правильнее не 410, а 301-редирект на неё.
# nginx
location = /old-page {
return 410;
}
# Apache (.htaccess, модуль mod_alias)
Redirect gone /old-page
С ошибкой 400 код 410 объединяет только класс: оба клиентские. 400 говорит «запрос составлен неверно», 410 — «запрос верный, но нужного ресурса больше не существует». Подробно про отсутствующие страницы — в разборе ошибки 404 Not Found.
Как проверить ответ сервера
Быстрее всего увидеть код ответа и полный набор заголовков — бесплатная проверка HTTP-заголовков и кода ответа на enterno.io. Введите адрес — и сразу увидите статус, заголовки запроса и ответа, редиректы и подсказки по безопасности. Это помогает отличить клиентскую ошибку 400 от серверной 5xx. Если вы диагностируете API, сравните заголовки успешного и падающего запроса: чаще всего разница видна сразу — лишний заголовок, неверный Content-Type или отсутствующий обязательный параметр.
Если 400 появляется только после перехода по ссылке, проверьте всю цепочку перенаправлений инструментом проверки редиректов: иногда запрос ломает промежуточный редирект, который теряет кодирование параметров или переводит HTTPS-запрос на HTTP-порт. А чтобы узнать об ошибке раньше пользователей, поставьте страницу или API-эндпоинт на мониторинг — он сообщит, если сайт начнёт отвечать 400 вместо 200.
Чек-лист для разработчика
Прежде чем закрывать баг с 400, пройдитесь по короткому списку. Он экономит часы отладки и предотвращает повторное появление ошибки в проде.
- Проверьте, что тело запроса соответствует заголовку
Content-Type. - Валидируйте JSON до отправки — линтером или схемой.
- Убедитесь, что заголовки и URL укладываются в лимиты сервера.
- Логируйте на сервере причину 400 — не отдавайте клиенту «голый» код без пояснения.
- Для API возвращайте машиночитаемое тело ошибки с полем
errorи описанием. - Кодируйте параметры URL и не собирайте адрес склейкой строк с пользовательским вводом.
Связанные материалы
Чтобы разобраться в кодах ответа глубже, изучите полный справочник HTTP-кодов, а также разборы соседних ошибок: 403 Forbidden и 404 Not Found. Если 400 связан с cookie, полезен материал про флаги безопасности cookie.
Частые вопросы
400 Bad Request — это ошибка на моей стороне или на стороне сайта?
Формально код 400 относится к классу клиентских ошибок 4xx: сервер сообщает, что запрос собран некорректно. Но спровоцировать её могут и настройки сервера — например, слишком строгие лимиты на размер заголовков. Начинайте диагностику с очистки cookie и кэша, затем проверяйте формирование запроса.
Почему 400 появляется только на одном сайте?
Почти наверняка виноваты повреждённые или раздутые cookie именно этого домена. Каждый сайт хранит свои cookie отдельно, поэтому проблема изолирована. Очистите данные конкретного сайта в настройках браузера или откройте его в режиме инкогнито — если там всё работает, дело точно в cookie или кэше.
Как исправить 400 при отправке JSON в API?
Проверьте, что тело запроса — валидный JSON без висячих запятых и пропущенных значений, а заголовок Content-Type: application/json совпадает с фактическим форматом. Прогоните запрос через curl -v, чтобы увидеть, что реально уходит на сервер, и валидируйте JSON любым линтером перед отправкой.
Что значит «Request failed with status code 400»?
Это сообщение библиотеки axios: сервер ответил кодом 400. Сама причина лежит в теле ответа — выведите err.response.data, и API обычно прямо назовёт недостающее или неверное поле.
Почему длинный URL вызывает 400?
У серверов есть лимит на длину строки запроса и размер заголовков (обычно несколько килобайт). Если заголовки его превышают, nginx или Apache обрывают запрос кодом 400; на слишком длинный сам URL они чаще отвечают 414, но некоторые приложения и прокси возвращают и 400. Решение для пользователя — сократить ссылку, для разработчика — увеличить large_client_header_buffers или передавать данные в теле POST-запроса.
Помогает ли перезагрузка страницы при ошибке 400?
Простое обновление помогает редко, потому что причина обычно в сохранённых данных. Эффективнее жёсткая перезагрузка с очисткой кэша (Ctrl+F5) и удаление cookie сайта. Если после этого ошибка исчезает — виноваты были клиентские данные; если нет — проблема в самом запросе или конфигурации сервера.