Błąd 400 Bad Request oznacza, że serwer odebrał żądanie, ale nie może go przetworzyć, bo jest ono nieprawidłowe: ma błędną składnię, za duże nagłówki albo dane w formacie, którego serwer się nie spodziewał. W odróżnieniu od błędów 5xx przyczyna leży zwykle po stronie klienta, czyli przeglądarki, aplikacji albo skryptu, który wysyła żądanie. Spotykam go najczęściej w dwóch sytuacjach: gdy użytkownik nie może wejść na stronę przez zbyt duże ciasteczka i gdy integracja z API wysyła dane w złym formacie. W tym wpisie pokazuję, jak diagnozuję i naprawiam oba przypadki.
Co wywołuje błąd 400
| Przyczyna | Typowa sytuacja | Komunikat, który pomaga ją rozpoznać |
|---|---|---|
| za duże nagłówki lub ciasteczka | strona przestaje działać u jednego użytkownika, a u innych działa; w domenie zebrało się dużo ciasteczek z narzędzi analitycznych i testów | Request Header Or Cookie Too Large w Nginx |
| niepoprawny adres URL | niezakodowane znaki specjalne, np. pojedynczy %, spacja lub polskie znaki w parametrach | log błędów serwera |
| nieprawidłowe dane w API | uszkodzony JSON, nagłówek Content-Type niezgodny z treścią, brak wymaganego pola | treść odpowiedzi API |
| HTTP wysłane na port HTTPS | błędna konfiguracja proxy lub przekierowań po wdrożeniu certyfikatu | The plain HTTP request was sent to HTTPS port |
| nieprawidłowe żądanie od przeglądarki lub proxy | uszkodzona pamięć podręczna, rozszerzenie modyfikujące nagłówki, firmowe proxy | błąd tylko w jednej przeglądarce lub sieci |
Zbyt duży przesyłany plik to inny przypadek: poprawnie skonfigurowany serwer zwraca wtedy kod 413, a nie 400. Jeśli przy wysyłaniu plików pojawia się 400, sprawdzam, czy aplikacja lub proxy nie zamieniają błędu 413 na ogólny 400.
Jak diagnozuję i naprawiam błąd 400
1. Sprawdzam, czy błąd dotyczy jednego użytkownika
Jeśli strona działa w trybie prywatnym przeglądarki albo na innym urządzeniu, przyczyną są niemal zawsze ciasteczka lub pamięć podręczna. Użytkownikowi wystarczy wtedy usunąć ciasteczka dla tej jednej domeny. Jako właściciel strony sprawdzam jednak, skąd wzięło się ich tak dużo, bo problem wróci. Najczęściej winne są skrypty testów, czatów i narzędzi analitycznych, które zapisują własne ciasteczka w każdej subdomenie. Gdy nie mogę ich ograniczyć, zwiększam limit nagłówków na serwerze:
# Nginx
large_client_header_buffers 4 16k;
# Apache
LimitRequestFieldSize 16380
2. Odtwarzam żądanie poza aplikacją
Przy integracjach z API kopiuję żądanie z zakładki Network w narzędziach deweloperskich jako polecenie curl i wysyłam je
ręcznie, zmieniając po jednym elemencie:
curl -i -X POST https://api.example.pl/v1/orders \
-H "Content-Type: application/json" \
-d '{"product_id": 123, "quantity": 2}'
Dobrze zaprojektowane API zwraca przy błędzie 400 opis problemu w treści odpowiedzi, np. nazwę brakującego pola. Dlatego zawsze czytam
treść odpowiedzi, a nie tylko kod. Najczęstsze przyczyny w tym kroku to dane wysłane jako formularz zamiast JSON, liczba przekazana jako
tekst i niezakodowane znaki w parametrach adresu. W kodzie zawsze koduję parametry funkcjami do tego przeznaczonymi, np.
encodeURIComponent() w JavaScripcie albo http_build_query() w PHP, zamiast sklejać adres ręcznie. Gdy problem leży głębiej w kodzie aplikacji, przechodzę do metod, którymi
debuguję kod JavaScript i PHP.
3. Czytam log serwera
Gdy błąd zwraca sam serwer WWW, a nie aplikacja, log błędów Nginx lub Apache podaje konkretny powód: za długi nagłówek, za długą linię żądania albo nieprawidłowy znak. Jak szybko wyszukać takie wpisy wśród tysięcy linii, pokazuje analiza logów serwera.
4. Sprawdzam konfigurację HTTPS i proxy
Komunikat o żądaniu HTTP wysłanym na port HTTPS pojawia się, gdy serwer za load balancerem lub CDN dostaje ruch nieszyfrowany na porcie
przeznaczonym dla szyfrowanego, albo gdy w konfiguracji serwera brakuje dyrektywy ssl przy porcie 443. Taki błąd zwykle wychodzi
po wdrożeniu certyfikatu, a jego przyczyny szukam tak samo jak przy innych
błędach certyfikatu SSL.
Błąd 400 a indeksowanie
Googlebot rzadko trafia na błąd 400, bo nie wysyła dużych ciasteczek ani danych z formularzy. Gdy jednak w raporcie indeksowania w Search Console pojawiają się adresy z kodem 400, prawie zawsze są to linki z niepoprawnie zakodowanymi parametrami, np. z filtrów albo wyszukiwarki wewnętrznej. Poprawiam wtedy generowanie tych linków w szablonie, a nie pojedyncze adresy.
Pozostałe błędy HTTP
Każdy kod błędu wskazuje na inną warstwę, więc diagnozę zaczynam od innego miejsca: