Naar hoofdinhoud springen

Handleidingen / HTTP-statuscodes uitgelegd

502 Bad Gateway: wat er achter de proxy brak, en hoe u het vindt

Een 502 Bad Gateway betekent dat een proxy voor uw site de backend om een antwoord vroeg en iets ongeldigs terugkreeg, of helemaal niets. De proxy werkt correct; hij meldt dat wat erachter zit down is, crasht, of het verkeerde protocol spreekt.

Wie een 502 teruggeeft en waarom

RFC 9110 definieert 502 voor een server die optreedt als gateway of proxy en een ongeldig antwoord ontving van een inbound server die hij benaderde tijdens het proberen te vervullen van het verzoek. Elke moderne stack heeft minstens zo'n sprong: nginx of Apache voor een applicatieserver, een load balancer voor een vloot, een CDN voor uw origin, of alle drie.

Die gelaagdheid is de sleutel tot het lezen van een 502. Het onderdeel dat antwoordde is gezond genoeg om een foutpagina te genereren. Het onderdeel erachter is dat niet. Een 502 splitst uw stack dus altijd in een werkende helft en een kapotte helft, en uw taak is uit te zoeken waar de grens ligt.

Zijn buren zeggen iets nauwers. Een 504 Gateway Timeout betekent dat de backend bereikbaar maar te traag was. Een 500 betekent dat de backend zelf draaide en een fout gooide. Een 502 betekent dat de backend een slecht antwoord gaf of helemaal geen antwoord. De volledige vergelijking staat in het 5xx-overzicht.

Veelvoorkomende oorzaken

  • Het backendproces draait niet. Een gecrashte appserver, een gestopte PHP-FPM-pool, een container die is afgesloten of zijn health check niet haalde. De proxy verbindt met een poort waarop niemand luistert.
  • De backend crashte midden in het verzoek. Een out-of-memory-kill of een segmentation fault sluit de verbinding voordat de responseheaders compleet zijn.
  • Verkeerd upstream-adres of -poort. Een config die na een wijziging naar de oude poort wijst, of naar een host die niet meer herleidt.
  • Protocolmismatch. De proxy spreekt gewoon HTTP tegen een poort die TLS verwacht, of andersom. De bytes zijn onparseerbaar, dus noemt de proxy het antwoord ongeldig.
  • Responseheaders te groot. Een te grote cookie of een ongewoon lange header overschrijdt de buffer van de proxy, en het antwoord wordt geweigerd in plaats van doorgegeven.
  • Keep-alive-mismatch. De proxy hergebruikt een inactieve verbinding die de backend al gesloten heeft, wat sporadische 502's produceert bij overigens normale belasting.
  • Herstarts en deploys. Elk venster waarin het oude proces is gestopt en het nieuwe nog geen verbindingen accepteert.
  • Alle backends ongezond. Een load balancer zonder geslaagde leden heeft nergens om het verzoek naartoe te sturen.

Het proxylog lezen, wat het onderzoek meestal beëindigt

De statuscode is generiek, maar de proxylogregel is specifiek. Bij nginx zijn dit de berichten die de moeite van herkennen waard zijn:

[error] connect() failed (111: Connection refused) while connecting to upstream,
        upstream: "http://127.0.0.1:8080/"

[error] upstream prematurely closed connection while reading response header
        from upstream

[error] recv() failed (104: Connection reset by peer) while reading response
        header from upstream

[error] upstream sent too big header while reading response header from upstream

[error] no live upstreams while connecting to upstream

Elk wijst ergens anders naartoe:

  • connect() failed (111: Connection refused). Niets luistert op dat adres en die poort. De backend is gestopt, gebonden aan een andere interface, of op een andere poort dan de config zegt.
  • upstream prematurely closed connection. De backend accepteerde het verzoek en stierf of hing dan op voordat het antwoord af was. Zoek naar crashes, out-of-memory-kills of een worker-time-out binnen de applicatie, niet bij nginx.
  • connection reset by peer. Vergelijkbaar, maar de verbinding werd actief gereset. Vaak een firewall ertussen, of een backend die een gepoolde verbinding sloot die de proxy nog als open beschouwde.
  • upstream sent too big header. Een buffergrootteprobleem in de proxy, geen fout in de backend. Het antwoord is geldig maar groter dan waarvoor de proxy geconfigureerd is.
  • no live upstreams. Health checks hebben elke backend als down gemarkeerd.

Hoe u het repareert

  1. Test de backend rechtstreeks, de proxy omzeilend. Vraag vanaf de proxy-host het upstream-adres zelf op:
    curl -sS -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8080/
    Een 200 hier met een 502 op de publieke URL betekent dat de fout in de proxyconfiguratie of de link tussen beide zit. Een geweigerde verbinding betekent dat de backend echt down is.
  2. Controleer dat de backend draait en luistert op het adres dat de proxy verwacht. Binden aan 127.0.0.1 terwijl de proxy een containeradres belt, is een veelvoorkomende oorzaak.
  3. Lees het foutenlog van de proxy en match het bericht met de lijst hierboven voordat u een configuratie wijzigt.
  4. Lees dan het backendlog. Een crash, een out-of-memory-kill of een worker-time-out op dezelfde seconde bevestigt het geval "prematurely closed". Stilte wijst terug naar connectiviteit.
  5. Verifieer het upstream-adres, de poort en het schema in de proxyconfig, vooral na een migratie of een containerherbouw.
  6. Verhoog de headerbuffers van de proxy als het log zegt dat de header te groot was, en zoek apart uit waarom de header groeide.
  7. Laat deploys overlappen. Start het nieuwe proces, wacht tot het een health check haalt, dan het oude leegtrekken en stoppen. Health-gated rolling updates verwijderen het herstartvenster dat deploy-tijd-502's helemaal veroorzaakt.

Een 502 betrappen die twintig seconden duurt

Deploy-tijd- en crash-loop-502's zijn kort. Een backend herstart, geeft twintig seconden lang fouten en herstelt, dus tegen de tijd dat iemand controleert, is de site in orde en is er niets meer om naar te kijken. Een geplande HTTP-check die continu draait, registreert die vensters met tijdstempels, wat "was vanochtend even raar" verandert in een patroon dat u kunt correleren met deploys en herstarts. Een 502 kan ook van een CDN-edge komen in plaats van uw origin, dus vanuit meerdere regio's controleren scheidt een wereldwijde backendstoring van een edge-probleem dat een deel van uw verkeer treft, wat waar gedistribueerde beschikbaarheidsmonitoring voor dient.

Nu controleren

Voer de gratis check uit op je eigen site, zonder account.

HTTP check

Dit permanent monitoren

Ontvang een melding zodra er iets misgaat: HostTracker controleert vanaf meer dan 300 locaties en waarschuwt je via e-mail, sms, Slack, Telegram en meer.

HostTracker-functies

Meer in dit onderdeel: HTTP-statuscodes uitgelegd