Przejdź do treści głównej

Poradniki / Kody statusu HTTP wyjaśnione

Kod statusu 499: co nginx rozumie przez client closed request

499 w logu nginx oznacza, że klient zamknął połączenie, zanim nginx zdążyło skończyć wysyłanie odpowiedzi. To nie jest część oficjalnego standardu HTTP; nginx wymyślił to wyłącznie na potrzeby własnego logu dostępu, żeby operatorzy mogli odróżnić "klient się poddał" od każdego innego typu awarii.

Co oznacza kod statusu 499

499 Client Closed Request jest specyficzne dla nginx i nigdy nie zostało zdefiniowane w żadnym RFC. Kody powyżej 99 i poniżej 600 są ogólnie zarezerwowane dla linii statusu HTTP, ale 499 to własna konwencja nginx, logowana, gdy nginx wykryje, że połączenie klienta padło, podczas gdy wciąż czekało na odpowiedź aplikacji upstream, albo podczas gdy wciąż wysyłało treść odpowiedzi z powrotem do klienta. Najczęstszy realny kształt tego to wolny upstream połączony z klientem, kartą przeglądarki albo load balancerem, którego własny timeout jest krótszy niż to, ile czasu miał zająć serwer, więc klient rozłącza się pierwszy.

Jak pojawia się w logach

Nigdy nie zobaczysz 499 jako kodu statusu zwróconego jakiemukolwiek klientowi, przeglądarce, curlowi czy innemu, bo z definicji klienta już nie ma, zanim nginx zdążyłoby mu go wysłać. Istnieje wyłącznie we własnym logu dostępu nginx:

10.0.0.12 - - [19/Sep/2026:14:02:11 +0000] "GET /api/report HTTP/1.1" 499 0 "-" "python-requests/2.31"

Rozmiar odpowiedzi 0 bajtów i moment względem znanego czasu odpowiedzi Twojego upstreama to dwa najbardziej użyteczne szczegóły: 499, które konsekwentnie ląduje mniej więcej przy timeoucie Twojego upstreama, z niczym odesłanym, wskazuje wprost na "backend był zbyt wolny i coś przestało czekać".

Co powoduje 499

  • Wolna aplikacja upstream. Backend zajmuje więcej czasu na odpowiedź, niż jest skłonny czekać jakiś klient albo pośrednik, czy to wolne zapytanie do bazy danych, zewnętrzne wywołanie API, czy faktycznie ciężkie obliczenia.
  • Timeout po stronie klienta krótszy, niż potrzebuje serwer. Zamknięta karta przeglądarki, aplikacja mobilna poddająca się przy niestabilnym połączeniu, albo timeout własnej biblioteki klienta HTTP uruchamiający się, zanim odpowiedź nadejdzie.
  • Load balancer albo proxy upstream przekraczające limit czasu pierwsze. Jeśli coś stoi między prawdziwym użytkownikiem końcowym a nginx, jego własny timeout może wywołać rozłączenie, które nginx zaloguje jako 499, mimo że prawdziwy użytkownik końcowy niczego wprost nie anulował.
  • Użytkownik odchodzący ze strony albo odświeżający. Ktoś klikający gdzie indziej z wolno wczytującej się strony, albo niecierpliwie odświeżający, zamyka trwające połączenie, zanim nginx skończyło.
  • Niespójne wartości timeoutu w całym łańcuchu. Klient, CDN, load balancer i sam nginx mogą mieć każdy inny timeout, a ten najkrótszy decyduje, kiedy zdarza się rozłączenie, niezależnie od tego, jak skonfigurowane są pozostałe.

Dlaczego nigdy nie pojawia się w przeglądarce

499 to nie odpowiedź, to notatka, którą nginx robi sobie na temat odpowiedzi, której nigdy nie zdążyło skończyć wysyłać. Użytkownik, którego karta wyprodukowała 499 w Twoich logach, nic nie widzi: żadnej strony błędu, żadnego kodu statusu, tylko stronę, która przestała się wczytywać, albo wskaźnik ładowania, który nigdy się nie rozwiązał, bo nie było żadnej odpowiedzi, którą przeglądarka mogłaby wyrenderować. To dokładnie dlatego poleganie na błędach zgłaszanych przez użytkowników całkowicie to przeoczy; jedynym miejscem, gdzie 499 jest widoczne, jest własny log dostępu serwera.

Jak naprawić i ograniczyć 499

Nie ma jednego ustawienia, które eliminuje 499, bo leżąca u podstaw przyczyna to wyścig między poddaniem się klienta a zakończeniem przez serwer, a naprawa zależy od tego, która strona tego wyścigu jest faktycznie zepsuta. Zacznij od ustalenia, czy upstream jest konsekwentnie wolny dla dotkniętej trasy, czy rozłączenia grupują się wokół jednego klienta, sieci albo pośrednika, bo to wskazuje na różne naprawy.

  1. Zbadaj najpierw czas odpowiedzi upstreama, bo wolny backend to najczęstsza leżąca u podstaw przyczyna. Sprawdź, ile faktycznie trwały dotknięte żądania na upstreamie, nie tylko że nginx zalogowało 499.
  2. Zsynchronizuj wartości timeoutu w całym łańcuchu, świadomie, zamiast zostawiać domyślną wartość każdej warstwy: klient, CDN, load balancer oraz własne proxy_read_timeout i proxy_connect_timeout nginx powinny być ustawione z jasnym zrozumieniem, który ma zadziałać pierwszy.
  3. Rozważ proxy_ignore_client_abort, jeśli pozwolenie upstreamowi dokończyć pracę nawet po rozłączeniu klienta ma znaczenie dla Twojej aplikacji, na przykład żeby dokończyć zapis, który nie powinien zostać przerwany w połowie:
    proxy_ignore_client_abort on;
    To nie zapobiega wpisowi w logu 499 dla oryginalnego rozłączenia; zmienia to, czy nginx utrzymuje działające żądanie upstream, zamiast je porzucić.
  4. Przyspiesz samą pracę na upstreamie tam, gdzie faktyczną przyczyną jest naprawdę wolny endpoint, bo żadne strojenie timeoutu nie naprawi backendu, który sam w sobie trwa zbyt długo; profiluj konkretne wolne zapytania albo wywołania stojące za dotkniętą trasą.
  5. Traktuj rosnący wskaźnik 499 jako prawdziwy sygnał, nie szum logów do odfiltrowania, bo zwykle oznacza to, że Twoja aplikacja zwolniła, albo że konfiguracja timeoutów jest gdzieś w łańcuchu niedopasowana.

Jak zapobiec, żeby to stało się awarią

Ponieważ 499 nigdy nie dociera do klienta jako widoczny błąd, naprawdę wolny endpoint może pozostać niezauważony, dopóki ktoś nie przeczyta logów dostępu, mimo że prawdziwi użytkownicy po cichu porzucają żądania. Zaplanowana kontrola HTTP mierzy rzeczywisty czas odpowiedzi bezpośrednio wobec endpointu i alarmuje, gdy się pogarsza, wyłapując spowolnienie, które produkuje 499, zanim urośnie do żądań całkowicie zawodzących. Monitorowanie z wielu lokalizacji pomaga też odróżnić naprawdę wolny backend od timeoutu, który wyzwala się tylko dla klientów na konkretnej ścieżce sieciowej.

Powiązane błędy

Zobacz 504 Gateway Timeout dla standardowego, widocznego dla klienta odpowiednika, gdy to sam nginx poddaje się w czekaniu na upstream, zamiast klienta poddającego się pierwszym, przegląd 4xx dla standardowej rodziny błędów klienta oraz 429 Too Many Requests dla innego rodzaju odrzucenia związanego z częstotliwością, a nie czasem.

Najczęściej zadawane pytania

Czy 499 to prawdziwy kod statusu HTTP?

Nie. To własna konwencja logowania nginx dla klienta, który rozłączył się przed zakończeniem odpowiedzi, i nigdy nie jest wysyłane przez łącze żadnemu klientowi, bo klienta już nie ma, zanim zostałoby wysłane.

Dlaczego moje narzędzie do monitorowania nigdy nie widzi 499?

Kontrola monitorująca sama jest klientem, i jeśli to ona się poddaje przy wolnej odpowiedzi, zgłosi własny błąd timeoutu, nie 499, bo nigdy nie otrzymuje odpowiedzi HTTP, z której mogłaby odczytać kod statusu. 499 pojawia się wyłącznie we wpisie własnego logu dostępu serwera dla tego żądania.

Czy 499 oznacza, że mój serwer się zawiesił?

Nie. Oznacza konkretnie, że serwer wciąż pracował, albo miał zacząć pracować, gdy klient się rozłączył. Awaria typowo wyprodukowałaby zamiast tego 502 albo 500, gdy już coś odpowiedziało.

Czy mogę zatrzymać przetwarzanie upstreama, gdy klient się rozłącza?

Domyślnie nginx ogólnie przestaje czekać na upstream, gdy klienta już nie ma, ale dokładne zachowanie zależy od ustawień proxy; proxy_ignore_client_abort on mówi nginx, żeby pozwoliło żądaniu upstream kontynuować, zamiast je porzucić.

Jaka jest najczęstsza naprawa dla częstych 499?

Zsynchronizowanie wartości timeoutu między klientem, dowolnym pośredniczącym proxy albo load balancerem, a samym nginx, w połączeniu z zajęciem się tym, co spowalnia upstream. Samo jedno z tych działań zwykle nie rozwiązuje trwałego wzorca.

Sprawdź teraz

Uruchom darmowe sprawdzenie na swojej stronie - bez zakładania konta.

HTTP check

Monitoruj to na stałe

Otrzymasz powiadomienie w chwili awarii: HostTracker sprawdza z ponad 300 lokalizacji i powiadamia e-mailem, SMS-em, przez Slack, Telegram i nie tylko.

Funkcje HostTracker

Więcej w tej sekcji: Kody statusu HTTP wyjaśnione