499 er ikke en statuskode – det er en dagbogsnotits
HTTP-standarden har en fast, officielt registreret liste over statuskoder. 499 står ikke på den liste. Den er en privat konvention fra nginx, brugt til at notere en hændelse, der ellers ikke har nogen god betegnelse: klienten gav op og lukkede forbindelsen, før serveren overhovedet nåede at sende et svar.
Fordi forbindelsen allerede er lukket, når nginx skriver linjen, er der ingenting at sende et svar til. 499 går aldrig over netværket. Ingen browser viser den. Ingen bot modtager den. Det eneste sted, den nogensinde dukker op, er i din egen access-log – en dagbogsnotits skrevet til dig selv, ikke en besked til nogen anden.
Samme hændelse, andre navne: Apache og IIS
Bruger du ikke nginx, betyder det ikke, at problemet forsvinder – det betyder blot, at det er gemt et andet sted. Apache skriver ikke en selvstændig statuskode for en afbrudt klient; du finder det som en linje uden normal byte-størrelse i access.log, eller som en »Connection reset by peer«-meddelelse i error.log. IIS gør noget tilsvarende: W3C-loggen kan vise en win32-statuskode i stedet for en almindelig HTTP-kode, hvor en værdi som 1236 betyder, at forbindelsen blev afbrudt lokalt.
| Webserver | Hvad der logges, når klienten giver op | Hvor du skal lede |
|---|---|---|
| nginx | Statuskode 499 (»Client Closed Request«) i access-loggen. | access.log – filtrér på status=499. |
| Apache | Ingen egen statuskode. Linjen får ofte en streg (»-«) i stedet for byte-størrelse, og error.log noterer »Connection reset by peer« eller en afbrudt forbindelse. | error.log – søg efter »reset by peer« eller afbrudte forbindelser, ikke access.log. |
| IIS | W3C-loggen viser ofte sc-status 0 sammen med en win32-status som 1236 (forbindelsen blev afbrudt lokalt) i stedet for en almindelig HTTP-kode. | IIS-loggens win32-statuskolonne – ikke HTTP-statuskolonnen. |
Leder du kun efter 4xx- og 5xx-koder i den almindelige statuskolonne, går du lige forbi denne hændelse på både Apache og IIS. Den er der – bare under et andet navn, i et andet felt.
Crawlerens tålmodighed er ikke den samme som Googlebots
Googlebot har haft mere end to årtier til at opbygge et adaptivt system, der tåler træghed fra et domæne og justerer sig over tid. Mange AI-crawlere er bygget til et helt andet brugsmønster. En crawler, der henter indhold i baggrunden til træning, kan i praksis have rummeligere tid til rådighed end en crawler, der skal levere et svar til et menneske, som venter i en chat lige nu – som OAI-SearchBot, ChatGPT-User eller Claude-User. De sidstnævnte er bygget til lav ventetid, fordi brugeren oplever hvert ekstra tiendedels sekund direkte.
Konsekvensen: en side, der svarer godt nok til, at et menneske ikke bemærker ventetiden, kan alligevel være for langsom for en crawler, der skal levere et færdigt svar, før brugeren mister tålmodigheden. Den grænse, crawleren arbejder mod, er strammere end den, du tester mod i din egen browser.
Hvor forsinkelsen faktisk opstår: tunge SSR-sider og kolde cache-hits
Tiden til første byte (TTFB) er selve flaskehalsen. To mønstre står for de fleste af tilfældene:
Tung server-side rendering uden cache. Hver forespørgsel bygger siden op på ny fra bunden – henter data, kører komponenttræet, serialiserer HTML – før en eneste byte kan sendes. Jo tungere den kæde er, desto længere venter crawleren i mørket.
Kolde cache-hits og kolde funktionsstarter. Første forespørgsel mod en side (eller mod en serverless-funktion, der ikke har kørt for nylig) betaler en opstartsomkostning, som de næste forespørgsler slipper for. Rammer en AI-crawler netop den koldstart – noget, der statistisk er mere sandsynligt for mindre besøgte sider, altså ofte netop de sider, der har mest brug for synlighed – er chancen for, at forbindelsen ryger, større end i din egen varme udviklingstest.
Fra 499 til forældet AI-svar: hele kæden
En enkelt 499 er ingen katastrofe. Et gentaget mønster er noget andet. Ser en crawler gentagne gange, at forbindelser til dit domæne ryger, før et svar kommer, er et rimeligt udfald over tid, at den nedprioriterer eller sjældnere vender tilbage til netop de sider – ikke fordi indholdet er dårligt, men fordi webstedet fremstår upålideligt at hente fra.
Lavere hentefrekvens betyder, at det, der allerede ligger gemt om dig – korrekt eller forældet – bliver stående længere uden at blive opdateret. En prisændring, en ny ydelse, en rettet fejl på siden: intet af det når frem til næste AI-svar, før crawleren faktisk formår at hente siden på ny. Det er dette, der gør 499 lydløs på nøjagtig samme måde som resten af serien: ingen fejlmeddelelse vises for nogen, og det symptom, du til sidst bemærker, er et AI-svar, der virker et hak bagefter virkeligheden.
Sådan tæller du 499 mod AI-crawlere i loggen
Selvtjek. Hent access-loggen for de seneste 30 dage, og gruppér linjerne på statuskode 499 (eller Apache/IIS-ækvivalenten fra tabellen ovenfor) kombineret med user agent. Del resultatet i to grupper: kendte AI-user agents (GPTBot, OAI-SearchBot, ChatGPT-User, ClaudeBot, Claude-User, PerplexityBot, Google-Extended) og alt andet.
Er andelen af 499 tydeligt højere for AI-botten end for almindelig menneskelig trafik på de samme sider, er det ikke indholdet, der er problemet – det er TTFB'en. Løsningen ligger da i caching, hurtigere rendering eller varme funktionsstarter, ikke i at omskrive teksten. Er andelen nogenlunde ens på tværs af al trafik, er det sandsynligvis en generel ydelsessag, der rammer alle besøgende lige, og bør prioriteres derefter.
Ofte stillede spørgsmål
Er 499 en officiel HTTP-statuskode?
Hvordan finder jeg det samme problem, hvis jeg ikke bruger nginx?
Hvor længe venter en AI-crawler, før den giver op?
Hjælper det bare at hæve en timeout-værdi i konfigurationen?
Var dette nyttigt?
