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
З боку відвідувача, у порядку, у якому ви, найімовірніше, з ними зіткнетеся:
- Завеликі чи пошкоджені кукі. Роками накопичені кукі для одного домену, або кукі, зіпсовані розширенням чи невдалим перенаправленням, регулярно дають саме повідомлення "400 Bad Request - request header or cookie too large", щойно загальний розмір заголовків перевищить ліміт сервера.
- Помилка в URL-адресі чи неправильне кодування. Зайвий символ, незакодований пробіл чи зламана послідовність відсоткового кодування в адресному рядку або у вставленому посиланні можуть не пройти парсинг як валідний синтаксис.
- Розширення браузера змінює запити. Блокувальники реклами, інструменти приватності й деякі VPN-розширення переписують заголовки чи рядок запиту, і помилка в одному з них може віддати серверу щось зіпсоване.
- Закешоване перенаправлення веде на зламану URL-адресу. Браузер іде за застарілим перенаправленням на URL-адресу, яка сама по собі невалідна, і 400 з'являється вже на місці призначення, а не на посиланні, яке ви натиснули.
- Завантаження файлу більше, ніж дозволяє сервер. Деякі конфігурації сервера відповідають на завеликий файл кодом 400 замість конкретнішого 413 Payload Too Large.
З боку власника сайту, приблизно в порядку, який варто перевіряти першим:
- Ліміти на розмір заголовків чи кукі виставлені надто низько для того, що застосунок насправді надсилає, особливо після додавання трекінгових кукі, JWT у заголовках чи механізму сесій, що росте з часом.
- Невалідний або відсутній заголовок Host, що може створити зворотний проксі чи неправильно налаштований клієнт, і який більшості серверів потрібен, щоб узагалі маршрутизувати запит.
- Content-Length, що не збігається з фактично надісланим тілом, що може спричинити зламаний клієнт чи проксі з багом посередині.
- Правила веб-фаєрвола застосунків чи ModSecurity відхиляють запит, синтаксис якого людині здається нормальним, але який збігається із захисним патерном, що WAF трактує як зіпсований.
- API навмисно відхиляє неправильний JSON кодом 400. Це правильна поведінка, а не баг: тіло запиту, яке не парситься як валідний JSON, або в якому бракує обов'язкового поля, що API перевіряє на рівні синтаксису, за задумом має повертати 400.
Як зрозуміти, хто винен
Відтворіть той самий запит у чистому середовищі: вікно приватного перегляду без розширень і накопичених кукі, або звичайний виклик curl на ту саму URL-адресу. Якщо чистий запит проходить успішно, причина була локальною, найчастіше кукі чи розширення. Якщо він провалюється однаково і з чистого клієнта, і звідкись іще, власні ліміти чи правила сервера відхиляють цілком коректно сформований запит, і найшвидший спосіб підтвердити це масштабно - запустити HTTP-перевірку з кількох локацій одночасно й порівняти код статусу, який повертає кожна з них.
Як виправити 400 Bad Request
Якщо ви відвідувач
- Спершу очистіть кукі для сайту, адже завеликі чи пошкоджені кукі - найпоширеніша причина. У більшості браузерів можна очистити кукі лише для одного сайту, не втративши всі інші сеанси входу.
- Повторіть спробу у вікні приватного перегляду. Чисте вікно не має накопичених кукі і, залежно від браузера, за замовчуванням вимикає більшість розширень, що одразу ізолює обидві поширені причини.
- Перевірте URL-адресу на одруківки чи зайві символи, особливо після вставлення посилання звідкись, де могли додати параметри відстеження чи зламати кодування.
- Вимикайте розширення по одному, якщо помилка зберігається у звичайному вікні, але зникає в приватному перегляді - так ви знайдете те, що переписує запит.
- Спробуйте інший пристрій чи мережу, щоб виключити captive-портал чи локальний проксі, що взагалі не пов'язаний із сайтом.
Якщо ви керуєте сайтом
- Підвищте ліміти заголовків і буферів, якщо застосунку справді потрібні більші. На nginx:
На Apache:large_client_header_buffers 4 16k;
На IIS перевірте іLimitRequestFieldSize 16384maxRequestLengthуweb.configдля тіла запиту, і налаштування реєстру HTTP.sysMaxFieldLengthдля окремих полів заголовків. - Скоротіть те, що ви фактично надсилаєте в кукі й заголовках, а не лише піднімайте стелю. Прибирання застарілих кукі, винесення великих токенів із заголовків і коротший час життя кукі запобігають поверненню проблеми з ростом використання.
- Перевірте обробку заголовка Host на зворотному проксі чи балансувальнику навантаження і переконайтеся, що він передає застосунку валідне, очікуване значення.
- Прочитайте логи WAF чи ModSecurity щодо конкретного правила, яке спрацювало, якщо перед застосунком щось таке стоїть; хибне спрацювання потребує точкового винятку, а не вимкнення всього набору правил.
- Переконайтеся, що 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 для запитів, відхилених через частоту, а не через синтаксис.
Часті запитання
Чому очищення кукі виправляє помилку 400?
Бо кукі їдуть разом із кожним запитом як заголовки, а сервер застосовує максимальний загальний розмір заголовків. Роки накопичених кукі, чи одна пошкоджена кукі, можуть підштовхнути загальний розмір за цей ліміт, і сервер відповідає 400 ще до того, як прочитає щось інше про запит.
Помилка 400 однакова на кожному сайті, який я відвідую?
Код і загальна причина - неправильний синтаксис запиту - усюди однакові, але точний ліміт, який перевищили, і точне формулювання сторінки помилки задає власна конфігурація сервера кожного сайту.
Чи має мій API повертати 400 для невалідних вхідних даних?
Так, коли вхідні дані не парсяться або в них бракує поля, яке API перевіряє на рівні синтаксису. Це 400 працює як задумано, а не баг, який треба виправляти послабленням валідації.
Чи може WAF спричинити помилку 400 на запиті, що виглядає цілком нормально?
Так. Правило WAF може позначити патерн в URL-адресі, заголовку чи тілі, що технічно є валідним HTTP, але збігається із захисною сигнатурою, і деякі конфігурації WAF відповідають узагальненим 400 замість конкретнішої сторінки блокування.
Яка різниця між 400 і 413?
413 - конкретний код для тіла запиту, що перевищує налаштований ліміт розміру. Багато серверів використовують його правильно, але деякі за тієї самої умови завеликого тіла відповідають натомість 400, тож не покладайтеся на сам код, щоб точно визначити причину - перевіряйте документацію чи логи самого сервера.