Een 502 Bad Gateway-fout betekent dat een server die als gateway of proxy optreedt een ongeldig antwoord kreeg van de server erachter. De bezoeker bereikte wel iets, meestal nginx, Apache, een load balancer of een CDN, maar die laag kreeg geen fatsoenlijk antwoord van je applicatie. De applicatie is gecrasht, start opnieuw op, luistert ergens anders of verbrak de verbinding halverwege.
Een 502 gaat dus over twee servers, niet over één. Deze gids laat zien hoe je achterhaalt welke laag hem teruggaf, hoe je de gebruikelijke oorzaken oplost en hoe je de volgende 502 eerder ziet dan je klanten.
Wat een 502 je vertelt
De meeste websites hebben minstens twee lagen tussen de bezoeker en de code. Vooraan zit een CDN of load balancer, een webserver zoals nginx neemt de verbinding aan, en een applicatieproces, zoals PHP-FPM, Node.js, Gunicorn of een Java-server, bouwt de pagina op. Elke laag stuurt het verzoek door naar de volgende en geeft het antwoord terug.
Een 502 verschijnt wanneer een van die lagen een verzoek doorstuurt en niets bruikbaars terugkrijgt. Vergelijk het met de andere gateway-fouten:
502 Bad Gateway: de upstream-server antwoordde met iets ongeldigs, resette de verbinding of weigerde haar.
503 Service Unavailable: de dienst is overbelast, in onderhoud of heeft geen gezonde server om het verzoek naartoe te sturen.
504 Gateway Timeout: de upstream-server antwoordde niet op tijd.
Een 502 betekent dus meestal kapot of niet actief, een 504 meestal traag. Ons overzicht van HTTP-statuscodes zet de rest van de familie op een rij, en de gids over 503-fouten behandelt overbelasting en onderhoud.
Vind de laag die de 502 teruggaf
Zoek uit wie er antwoordde voordat je iets verandert. De foutpagina en de response headers zeggen het meestal letterlijk:
curl -sI https://www.example.com/checkout
HTTP/2 502
server: cloudflare
cf-ray: 8d2f1c3a5b7e4a21-ARN
server: cloudflare met een Cloudflare-foutpagina die je host noemt: Cloudflare bereikte je origin, en de origin faalde.
server: nginx of Apache met een kale foutpagina: je eigen webserver kon de applicatie erachter niet bereiken.
server: awselb/2.0 of een andere load balancer: de load balancer kreeg geen geldig antwoord van enig target, of van het target dat hij koos.
Vergelijk het daarna met een verzoek dat de buitenste laag overslaat. Stuur het rechtstreeks naar de origin of naar de applicatiepoort op de server zelf:
curl -sI –resolve www.example.com:443:203.0.113.10 https://www.example.com/checkout
curl -sI http://127.0.0.1:3000/checkout
Antwoordt de applicatie lokaal wel maar via de proxy niet, kijk dan naar de configuratie van de proxy. Antwoordt ze ook lokaal niet, dan ligt het probleem bij de applicatie.
Veelvoorkomende oorzaken en hoe je ze oplost
Het applicatieproces is gecrasht of start opnieuw op
De meest voorkomende oorzaak. Het proces achter de proxy had te weinig geheugen, liep tegen een onafgehandelde exception aan of werd gestopt, en de proxy heeft niets om mee te praten. nginx logt dat onomwonden:
connect() failed (111: Connection refused) while connecting to upstream,
upstream: “http://127.0.0.1:3000/checkout”
Controleer of het proces draait en waarom het stopte:
systemctl status myapp
journalctl -u myapp –since “30 min ago”
dmesg -T | grep -i “killed process”
Een regel van de out-of-memory killer van de kernel betekent dat de server door zijn geheugen heen was. Herstarten brengt de site terug, maar de echte oplossing is meer geheugen, minder workers of een gevonden en gedichte geheugenlek. Zorg dat de service na een crash vanzelf herstart, bijvoorbeeld met Restart=on-failure in de systemd-unit.
PHP-FPM ligt eruit of heeft geen workers meer
Op PHP-sites geeft nginx verzoeken via een socket of poort door aan PHP-FPM. Is PHP-FPM gestopt, klopt het pad naar de socket niet of houden de rechten op de socket nginx buiten, dan geeft elke PHP-pagina een 502:
connect() to unix:/run/php/php8.3-fpm.sock failed (2: No such file or directory)
Die melding volgt meestal op een PHP-upgrade: nginx wijst nog naar de socket van de oude versie. Laat fastcgi_pass naar de nieuwe socket wijzen en herlaad nginx. Zegt de log in plaats daarvan server reached pm.max_children, dan is elke worker bezet, vaak omdat ze wachten op een trage database of een externe API. Verhoog de limiet alleen als de server geheugen over heeft; zoek anders uit wat de workers bezighoudt.
Verkeerd upstream-adres of verkeerde poort
Na een migratie, een nieuwe build van een container of een gewijzigde poort kan de proxy nog naar het oude adres doorsturen. De foutlog toont het adres dat hij probeerde. Vergelijk dat met waar de applicatie werkelijk luistert:
ss -ltnp | grep -E ‘:(3000|8000|9000)’
In Docker en Kubernetes is de oorzaak vaak een servicenaam die niet meer resolvet, een container die binnen de container op 127.0.0.1 luistert in plaats van op 0.0.0.0, of een readiness check die elke pod als niet gereed markeert.
De upstream verbrak de verbinding te vroeg
upstream prematurely closed connection while reading response header betekent dat de applicatie het verzoek aannam en daarna ophing. Typische redenen zijn een crash halverwege het verzoek, een worker die werd gestopt omdat hij zijn eigen tijdslimiet overschreed, zoals –timeout van Gunicorn of max_execution_time van PHP, en keep-alive-verbindingen die de applicatie eerder sluit dan de proxy verwacht. Stem de timeouts zo af dat de proxy iets langer wacht dan de applicatie, nooit andersom, en kijk welke verzoeken traag genoeg zijn om de limiet te raken.
Te grote response headers
Grote cookies of veel Set-Cookie-headers kunnen groter zijn dan de buffer van nginx voor de response headers van de upstream. nginx logt dan upstream sent too big header while reading response header from upstream en geeft een 502 terug. Verhoog de buffers voorzichtig:
proxy_buffer_size 16k;
proxy_buffers 8 16k;
# for PHP-FPM
fastcgi_buffer_size 32k;
fastcgi_buffers 8 16k;
Zoek daarna uit waarom de headers zo groot werden. Een cookie die bij elk bezoek groeit, is een bug die het oplossen waard is.
Het CDN kan je origin niet bereiken
Geeft een CDN of load balancer een 502, kijk dan wat er tussen dat CDN en je server zit. Een firewall die de IP-ranges van het CDN blokkeert, een origin-certificaat dat het CDN niet accepteert, een origin die alleen HTTP/1.0 spreekt of verbindingen te snel sluit, of een DNS-record dat naar een oude server wijst: ze lopen allemaal op dezelfde manier af. Test de origin rechtstreeks, zoals hierboven, en controleer de firewall en de TLS-instellingen aan beide kanten.
502-fouten tijdens deploys
Duiken 502-fouten telkens tien of twintig seconden op, en altijd rond een release, dan veroorzaakt de deploy ze zelf. Het oude proces stopt, het nieuwe heeft een paar seconden nodig om op te starten, en elk verzoek daartussen faalt. De oplossing is een releasevolgorde waarin er altijd iets klaarstaat om te antwoorden:
Start de nieuwe versie naast de oude.
Wacht tot de health check slaagt. Onze gids over het bouwen van een health check endpoint laat zien wat die check moet testen.
Zet het verkeer over naar de nieuwe versie.
Laat de oude versie haar lopende verzoeken afmaken en stop haar daarna.
Procesmanagers en orchestrators ondersteunen dit als rolling of zero-downtime reloads. Gebruik die in plaats van een gewone herstart.
Hoe monitoring 502-fouten opvangt
Een 502 duurt vaak kort. Een deploy veroorzaakt twintig seconden aan fouten, een worker crasht en herstart, een cache verbergt het probleem voor de meeste bezoekers. Tegen de tijd dat iemand de site opent, werkt alles weer, maar een klant die midden in de checkout zat, zag de fout wel.
Een uptime monitor vraagt je pagina’s volgens een schema op en legt bij elke check de statuscode en de responstijd vast. Een 502 is een mislukte check. Waar het om draait, is wat er daarna gebeurt:
Bevestig de fout. Eén mislukt verzoek kan een blip zijn. Uptimecheck controleert zo vaak als elke minuut vanuit Stockholm, Londen en New York, en bevestigt elke fout vanaf een tweede locatie voordat er een incident opent, zodat een eenmalige reset niemand wakker maakt.
Toon het bewijs. Het incident bevat het foutieve antwoord, dus je ziet de statuscode, de server-header en de foutpagina, plus een screenshot van wat bezoekers zagen. Antwoordde de server helemaal niet, dan krijg je in plaats daarvan het netwerkpad.
Bereik de juiste mensen. Alerts gaan naar e-mail, Slack, Microsoft Teams, PagerDuty, webhooks en de andere alertkanalen die je team gebruikt.
Houd meer in de gaten dan de homepage. Die wordt vaak door een CDN gecachet en blijft werken terwijl checkout, inloggen en de API een 502 geven. Voeg uptime monitors toe voor de pagina’s die geld opleveren en API-monitors voor de endpoints die je apps aanroepen. Komt de 502 van een applicatie die door haar geheugen heen was, dan toont servermonitoring de geheugencurve naast de storing.
Checklist voor een 502
Lees de server-header en de foutpagina om te zien welke laag de 502 teruggaf.
Vraag de origin en de applicatiepoort rechtstreeks op om het probleem te lokaliseren.
Lees de foutlog van de proxy voor dezelfde tijdstempel: geweigerd, te vroeg gesloten of te grote header.
Controleer of het applicatieproces draait, en waarom het stopte als dat niet zo is.
Vergelijk het upstream-adres, de socket en de poort met waar de applicatie luistert.
Stem de timeouts zo af dat de proxy langer wacht dan de applicatie.
Deploy door de nieuwe versie te starten voordat je de oude stopt.
Monitor belangrijke pagina’s en endpoints elke minuut en bevestig elke fout voordat je alarmeert.