Statuscode 499: wat nginx bedoelt met client closed request
Een 499 in een nginx-log betekent dat de client de verbinding sloot voordat nginx klaar was met het versturen van een antwoord. Het maakt geen deel uit van de officiële HTTP-standaard; nginx bedacht het puur voor zijn eigen toegangslog zodat beheerders "de client gaf het op" konden onderscheiden van elke andere soort storing.
Wat de statuscode 499 betekent
499 Client Closed Request is specifiek voor nginx en nooit gedefinieerd in enige RFC. Codes boven 99 en onder 600 zijn in het algemeen gereserveerd voor HTTP-statusregels, maar 499 is nginx's eigen conventie, gelogd wanneer nginx detecteert dat de verbinding van de client wegviel terwijl hij nog wachtte op antwoord van de upstream-applicatie, of terwijl hij de responsbody nog terugstuurde naar de client. De meest voorkomende praktijkvorm is een trage upstream in combinatie met een client, browsertab, of loadbalancer wiens eigen timeout korter is dan hoe lang de server erover zou doen, waardoor de client als eerste ophangt.
Hoe het in logs verschijnt
U zult 499 nooit als statuscode teruggegeven zien aan een client, browser, curl, of anderszins, omdat de client per definitie al weg is tegen de tijd dat nginx hem zou hebben verstuurd. Het bestaat alleen in nginx's eigen toegangslog:
10.0.0.12 - - [19/Sep/2026:14:02:11 +0000] "GET /api/report HTTP/1.1" 499 0 "-" "python-requests/2.31"
De antwoordgrootte van 0 bytes en de timing ten opzichte van de bekende responstijd van uw upstream zijn de twee nuttigste details: een 499 die consequent rond de timeout van uw upstream landt, zonder dat er iets werd teruggestuurd, wijst regelrecht op "de backend was te traag en iets gaf het wachten op."
Wat een 499 veroorzaakt
- Een trage upstream-applicatie. De backend doet langer over antwoorden dan een client of tussenpersoon bereid is te wachten, of dat nu een trage databasequery is, een externe API-aanroep, of een echt zware berekening.
- Een timeout aan de clientkant die korter is dan wat de server nodig heeft. Een gesloten browsertab, een mobiele app die het opgeeft bij een wankele verbinding, of de eigen timeout van een HTTP-clientbibliotheek die afgaat voordat het antwoord aankomt.
- Een loadbalancer of upstream-proxy die als eerste een timeout krijgt. Staat er iets tussen de echte eindgebruiker en nginx, dan kan de eigen timeout daarvan een verbreking triggeren die nginx als 499 logt, ook al annuleerde de echte eindgebruiker nooit expliciet iets.
- Een gebruiker die wegnavigeert of ververst. Iemand die wegklikt van een traag ladende pagina, of ongeduldig ververst, sluit de lopende verbinding voordat nginx klaar was.
- Timeoutwaarden die inconsistent zijn over de hele keten. Een client, een CDN, een loadbalancer, en nginx zelf kunnen elk een andere timeout hebben, en welke daarvan het kortst is bepaalt wanneer de verbreking plaatsvindt, ongeacht waarvoor de andere geconfigureerd zijn.
Waarom het nooit in een browser verschijnt
499 is geen antwoord, het is een notitie die nginx voor zichzelf maakt over een antwoord dat het nooit klaar kreeg om te versturen. Een gebruiker wiens tabblad een 499 in uw logs produceerde ziet helemaal niets: geen foutpagina, geen statuscode, alleen een pagina die stopte met laden of een draaiend icoontje dat nooit klaar werd, omdat er geen antwoord was voor de browser om weer te geven. Dit is precies waarom vertrouwen op door gebruikers gemelde fouten dit volledig mist; de enige plek waar een 499 zichtbaar is, is het eigen toegangslog van de server.
Hoe u 499's oplost en vermindert
Er is geen enkele instelling die 499's elimineert, aangezien de onderliggende oorzaak een race is tussen de client die het opgeeft en de server die klaar raakt, en de oplossing hangt af van aan welke kant van die race daadwerkelijk iets kapot is. Begin met vaststellen of de upstream consequent traag is voor de betrokken route, of dat de verbrekingen zich concentreren rond één client, netwerk, of tussenpersoon, aangezien die op verschillende oplossingen wijzen.
- Onderzoek eerst de responstijd van de upstream, aangezien een trage backend de meest voorkomende onderliggende oorzaak is. Kijk hoe lang de betrokken verzoeken daadwerkelijk over de upstream deden, niet alleen dat nginx een 499 logde.
- Stem timeoutwaarden bewust op elkaar af over de hele keten, in plaats van de standaardwaarde van elke laag te laten staan: client, CDN, loadbalancer, en de eigen
proxy_read_timeoutenproxy_connect_timeoutvan nginx zouden ingesteld moeten worden met een duidelijk beeld van welke als eerste hoort af te gaan. - Overweeg
proxy_ignore_client_abortals het voor uw applicatie belangrijk is dat de upstream zijn werk afmaakt zelfs nadat de client de verbinding verbreekt, bijvoorbeeld om een schrijfactie te voltooien die niet halverwege mag blijven staan:
Dit voorkomt niet dat het 499-logitem voor de oorspronkelijke verbreking ontstaat; het verandert alleen of nginx het upstream-verzoek toch laat doorlopen.proxy_ignore_client_abort on; - Versnel het daadwerkelijke upstream-werk waar de hoofdoorzaak echt een traag endpoint is, aangezien geen enkele hoeveelheid timeout-afstelling een backend herstelt die op zichzelf te lang doet; profileer de specifieke trage queries of aanroepen achter de betrokken route.
- Behandel een stijgend percentage 499's als een echt signaal, geen loggeruis om weg te filteren, aangezien het meestal betekent dat uw applicatie trager is geworden of dat uw timeoutconfiguratie ergens in de keten niet klopt.
Hoe u voorkomt dat het een storing wordt
Omdat 499 de client nooit bereikt als een zichtbare fout, kan een echt traag endpoint makkelijk onopgemerkt blijven totdat iemand de toegangslogs leest, terwijl echte gebruikers stilletjes verzoeken opgeven. Een geplande HTTP-controle meet de daadwerkelijke responstijd rechtstreeks tegen het endpoint en waarschuwt wanneer die verslechtert, waardoor de vertraging die de 499's veroorzaakt wordt opgevangen voordat die uitgroeit tot ronduit falende verzoeken. Monitoring vanaf meerdere locaties helpt ook een echt trage backend te scheiden van een timeout die alleen afgaat voor clients op een bepaald netwerkpad.
Gerelateerde fouten
Zie 504 Gateway Timeout voor het standaard, voor de client zichtbare equivalent wanneer nginx zelf het wachten op de upstream opgeeft in plaats van dat de client als eerste opgeeft, het 4xx-overzicht voor de standaard familie van clientfouten, en 429 Too Many Requests voor een ander soort weigering gebonden aan snelheid in plaats van timing.
Veelgestelde vragen
Is 499 een echte HTTP-statuscode?
Nee. Het is nginx's eigen logconventie voor een client die de verbinding verbrak voordat het antwoord klaar was, en het wordt nooit over de lijn naar een client verstuurd aangezien de client al weg is tegen de tijd dat het verstuurd zou worden.
Waarom ziet mijn monitoringtool nooit een 499?
Een monitoringcontrole is zelf een client, en als die degene is die het opgeeft bij een traag antwoord, rapporteert hij zijn eigen timeoutfout, geen 499, aangezien hij nooit een HTTP-antwoord ontvangt om een statuscode uit af te lezen. 499 verschijnt alleen ooit in het eigen toegangslogitem van de server voor dat verzoek.
Betekent een 499 dat mijn server gecrasht is?
Nee. Het betekent specifiek dat de server nog aan het werk was, of op het punt stond te beginnen, toen de client de verbinding verbrak. Een crash zou doorgaans in plaats daarvan een 502 of 500 opleveren, zodra er iets antwoordde.
Kan ik upstream-verwerking stoppen wanneer een client de verbinding verbreekt?
Standaard stopt nginx over het algemeen met wachten op de upstream zodra de client weg is, maar het exacte gedrag hangt af van uw proxy-instellingen; proxy_ignore_client_abort on vertelt nginx het upstream-verzoek te laten doorlopen in plaats van het te laten vallen.
Wat is de meest voorkomende oplossing voor frequente 499's?
Timeoutwaarden op elkaar afstemmen over de client, elke tussenliggende proxy of loadbalancer, en nginx zelf, gecombineerd met het aanpakken van wat de upstream in de eerste plaats traag maakt. Geen van beide alleen lost meestal een aanhoudend patroon op.