Du siehst einen 502-Fehler in deiner Anwendung und Nginx ist als Reverse Proxy im Spiel? Dann bedeutet das: Der Proxy hat vom Upstream (z. B. PHP-FPM, Node.js, Gunicorn, Java, API) keine gültige Antwort bekommen oder die Verbindung ist fehlgeschlagen. In diesem Leitfaden bekommst du eine konzentrierte, praxistaugliche Anleitung – von der schnellen Diagnose über typische Fehlerbilder bis zu robusten Fixes und präventiven Best Practices.
Was der Fehler konkret bedeutet – und wie er sich abgrenzt
Ein 502 Bad Gateway wird von Nginx ausgegeben, wenn die Kommunikation zum Upstream fehlschlägt oder die Antwort ungültig ist. Das kann an nicht laufenden Diensten, falschen Sockets/Ports, Timeouts, DNS-, Netzwerk- oder SSL/TLS-Problemen liegen. Wichtig ist die Abgrenzung zu ähnlichen Codes:
| HTTP-Status | Bedeutung | Typische Ursache | Wo suchen? |
|---|---|---|---|
| 502 Bad Gateway | Nginx erhielt vom Upstream keine gültige Antwort. | Upstream down, falscher Socket/Port, Timeouts, TLS-/DNS-Probleme. | Nginx-Error-Log, Upstream-Logs, Netzwerk. |
| 504 Gateway Timeout | Antwort des Upstreams kam nicht rechtzeitig. | Zu knappes Timeout, langsame Queries, Überlastung. | Timeout-Settings, Upstream-Performance. |
| 503 Service Unavailable | Der Dienst ist nicht verfügbar oder überlastet. | Wartungsmodus, Throttling, keine Worker frei. | Upstream-Status, Auto-Scaling, Rate Limits. |
So arbeitet Nginx als Reverse Proxy – der Weg der Anfrage
- Browser/Client sendet eine HTTP/HTTPS-Anfrage an Nginx.
- Nginx terminiert ggf. TLS, prüft Location/Server-Block und leitet an den Upstream weiter (z. B.
proxy_passoderfastcgi_pass). - Der Upstream (PHP-FPM, Node.js, Gunicorn, Java, …) verarbeitet die Anfrage.
- Nginx liest die Antwort-Header/-Body und liefert an den Client zurück.
Merke: Ein 502 ist kein Browser-Fehler. Er entsteht auf oder hinter Nginx, sobald zwischen Proxy und Upstream etwas schiefläuft.

Häufige Ursachen – Symptome, Checks und Fixes
1) Upstream-Server läuft nicht oder ist nicht erreichbar
Symptome: Fehler im Nginx-Error-Log wie connect() failed (111: Connection refused) oder no live upstreams.
- Schnelltest: Prüfe den Dienststatus und höre auf den richtigen Port/Socket.
systemctl status php8.2-fpm
systemctl status nginx
ss -lntp | grep -E '9000|3000|8000'
Fix: Upstream starten/neustarten, Autostart konfigurieren, Crash-Ursache im Upstream-Log klären.
2) Fehlkonfiguration in Nginx (falscher Socket/Port/IP)
Symptome: 502 nach Deploy oder Config-Änderung; Error-Log zeigt falsche Pfade oder Verbindungsfehler.
- Schnelltest: Prüfe
fastcgi_pass/proxy_passund teste die Gegenstelle.
nginx -t
curl -svo /dev/null http://127.0.0.1:3000/
Fix: IP/Port/Socket in Nginx und Upstream harmonisieren, Tippfehler in Unix-Socket-Pfaden korrigieren.
3) Socket- und Datei-Berechtigungen
Symptome: Nginx-Error-Log enthält permission denied beim Zugriff auf den Unix-Socket.
- Schnelltest: Prüfe Owner/Gruppe/Mode der Socket-Datei und den Nginx-User.
ls -l /run/php/php8.2-fpm.sock
grep -R '^user' /etc/nginx/nginx.conf
Fix: Owner/Gruppe/Berechtigungen anpassen (z. B. Gruppe www-data), PHP-FPM-Pool und Nginx-User abstimmen.
4) Timeouts und langsame Responses
Symptome: upstream timed out oder 502 bei Last/langsamen Queries.
- Schnelltest: Latenzen/DB-Abfragen prüfen, Timeout-Werte vergleichen.
| Komponente | Typische Defaults | Relevante Direktiven | Hinweis |
|---|---|---|---|
| Nginx (Proxy) | ~60s | proxy_read_timeout, proxy_connect_timeout, proxy_send_timeout |
Je nach Distribution/Version variabel. |
| Nginx (FastCGI) | ~60s | fastcgi_read_timeout |
Für PHP-FPM entscheidend. |
| PHP/PHP-FPM | ~20–30s | max_execution_time, request_terminate_timeout |
Zu kurzes Limit → FPM beendet Worker. |
Fix: Timeouts maßvoll erhöhen und Upstream-Performance (Queries, Caching) verbessern.
5) Ressourcenerschöpfung und Überlastung
Symptome: Sporadische 502 unter Last, OOM-Killer, hohe CPU, „Too many open files“.
- Schnelltest: CPU/RAM/FD-Limits prüfen, DDoS/Traffic-Spitzen ausschließen.
htop
free -h
ulimit -n
dmesg | grep -i -E 'out of memory|oom'
Fix: Worker/Instanzen skalieren, Limits erhöhen, Backpressure/Queueing einführen, Caches aktivieren.
6) DNS-Auflösungsprobleme
Symptome: 502 bei Domain-basierten Upstreams, sporadische Failures.
- Schnelltest: DNS-Resolver und Latenzen prüfen.
dig backend.internal A
cat /etc/resolv.conf
Fix: Stabilen Resolver hinterlegen (resolver-Direktive in Nginx), bei Bedarf IP statt Hostname verwenden.
7) SSL/TLS-Inkompatibilitäten zwischen Nginx und Upstream
Symptome: Handshake-Fehler im Error-Log, abgelaufene Zertifikate, falsche SNI/Protokolle.
- Schnelltest: Mit
openssl s_clientprüfen, Cipher/Protokolle vergleichen.
openssl s_client -connect backend.internal:443 -servername backend.internal
Fix: Zertifikate erneuern, TLS-Parameter harmonisieren, ggf. proxy_ssl_server_name on; setzen.
8) Firewall- und Netzwerkregeln
Symptome: Verbindungen von Nginx zum Upstream werden gedroppt/abgelehnt.
- Schnelltest: Erreichbarkeit von Ports prüfen, Security Groups/Firewall-Regeln verifizieren.
nc -zv 10.0.0.15 9000
sudo iptables -L -n
Fix: Regeln anpassen, Routen prüfen, interne LBs/Service-Mesh beachten.
Typische Log-Meldungen und schnelle Zuordnung
| Logzeile (gekürzt) | Wahrscheinliche Ursache | Schnelltest | Sofortmaßnahme |
|---|---|---|---|
connect() failed (111: Connection refused) |
Upstream nicht erreichbar/Port falsch | ss -lntp, curl lokal |
Upstream starten, Port korrigieren |
upstream timed out |
Timeout überschritten | Langsame Queries, Limits prüfen | Timeouts anpassen, Upstream tunen |
no live upstreams |
Alle Targets down/markiert | Health/Status checken | Instanzen fixen/aus Pool nehmen |
permission denied auf Socket |
Berechtigungen falsch | ls -l auf Socket |
Owner/Gruppe/Mode richten |
bad gateway while reading response |
Ungültige/abgebrochene Antwort | Upstream-Logs prüfen | Stabilität/Protokoll prüfen |
Dein Diagnose-Playbook (Schritt für Schritt)
- Error-Logs sofort checken:
tail -n 200 /var/log/nginx/error.log grep -i upstream /var/log/nginx/error.log - Upstream-Status prüfen:
systemctl status php8.2-fpm journalctl -u php8.2-fpm -n 200 --no-pager - Port/Socket verifizieren:
ss -lntp ls -l /run/php/ - Direkt vom Nginx-Host testen:
curl -sv http://127.0.0.1:3000/health curl -sv --unix-socket /run/php/php8.2-fpm.sock http://localhost/status - Timeouts und Performance sichten:
grep -R "timeout" /etc/nginx/conf.d /etc/nginx/nginx.conf - Firewall/DNS/TLS prüfen:
nc -zv backend.internal 443 dig backend.internal openssl s_client -connect backend.internal:443 -servername backend.internal - Ressourcenlage:
htop free -h ulimit -n - Konfiguration testen und neu laden:
nginx -t && systemctl reload nginx
Pro-Tipp: Reproduziere den Fehler mit korreliertem Zeitstempel. Markiere im Log mittels
echoeine „Leitboje“, damit du interessante Stellen schneller findest.

Konkrete Lösungen mit Beispielen
Nginx korrekt auf PHP-FPM per Unix-Socket ausrichten
# /etc/nginx/sites-enabled/example.conf
server {
listen 80;
server_name example.test;
root /var/www/html/public;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
fastcgi_read_timeout 90s;
}
}
; /etc/php/8.2/fpm/pool.d/www.conf
user = www-data
group = www-data
listen = /run/php/php8.2-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
pm = dynamic
pm.max_children = 20
; request_terminate_timeout verhindert hängende Worker:
request_terminate_timeout = 60s
Wichtig: listen im Pool und fastcgi_pass in Nginx müssen exakt zusammenpassen. Achte auf Besitzer und Modus des Sockets.
Nginx auf TCP-Upstream (Node.js, Gunicorn, Java)
upstream app_backend {
server 127.0.0.1:3000 max_fails=3 fail_timeout=10s;
keepalive 32;
}
server {
listen 80;
server_name app.local;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_connect_timeout 5s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
proxy_pass http://app_backend;
}
error_page 502 504 /custom_50x.html;
location = /custom_50x.html {
root /var/www/errors;
internal;
}
}
TLS zum Upstream absichern (falls intern HTTPS)
upstream secure_backend {
server backend.internal:443;
}
server {
listen 443 ssl http2;
server_name www.example.com;
# ... Zertifikate für den Client-Traffic ...
location / {
proxy_ssl_server_name on;
proxy_ssl_protocols TLSv1.2 TLSv1.3;
proxy_ssl_verify off; # Besser: on mit vertrauenswürdigem CA-Store
proxy_pass https://secure_backend;
}
}
Timeouts gezielt erhöhen – und sinnvoll begrenzen
- Wenn Upstream langsam ist:
proxy_read_timeoutbzw.fastcgi_read_timeoutanheben. - Wenn Verbindungen hängen:
proxy_connect_timeoutkürzer halten, um schneller zu failen.
proxy_connect_timeout 5s;
proxy_send_timeout 30s;
proxy_read_timeout 60s;
fastcgi_read_timeout 90s;
Setze Timeouts nicht unendlich hoch. Stabilität erreichst du primär durch Optimierung der Upstream-Performance.
Socket-Berechtigungen sauber setzen
chown www-data:www-data /run/php/php8.2-fpm.sock
chmod 660 /run/php/php8.2-fpm.sock
systemctl restart php8.2-fpm
Skalierung, Caching und Lastverteilung
- Horizontal skalieren: Mehr Upstream-Instanzen, z. B. mehrere PHP-FPM-Worker-Hosts.
- Health Checks: Nur gesunde Instanzen erhalten Traffic.
- Caching: Statische Inhalte und gecachte API-Antworten entlasten den Upstream.
- CDN: Offload von statischen Inhalten und Edge-Caching.
Beispiel: Health Checks und Load Balancing
upstream api_pool {
server 10.0.0.11:8000 max_fails=2 fail_timeout=10s;
server 10.0.0.12:8000 max_fails=2 fail_timeout=10s;
keepalive 64;
}
server {
listen 80;
server_name api.example.com;
location /health {
access_log off;
return 200 "OK\n";
}
location / {
proxy_pass http://api_pool;
proxy_next_upstream error timeout invalid_header http_502 http_504;
proxy_next_upstream_tries 3;
}
}
DNS stabilisieren
http {
resolver 1.1.1.1 8.8.8.8 valid=300s;
resolver_timeout 5s;
# ...
}
Absicherung gegen Überlastung
- Rate Limiting: Schutz vor plötzlichen Peaks/DDoS.
- Circuit Breaker (Applikationsebene): Fehlerwellen eindämmen.
- Queueing/Backpressure: Systemdruck beherrschbar machen.
Produktionsnahe Nginx-Basiseinstellungen (Ausschnitt)
worker_processes auto;
events { worker_connections 4096; }
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65s;
keepalive_requests 1000;
# Logging
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'rt=$request_time uct=$upstream_connect_time '
'urt=$upstream_response_time uht=$upstream_header_time';
access_log /var/log/nginx/access.log main;
# Timeouts (konservativ anpassen)
proxy_connect_timeout 5s;
proxy_send_timeout 30s;
proxy_read_timeout 60s;
# DNS-Resolver
resolver 1.1.1.1 8.8.8.8 valid=300s;
}
Besonderheiten in Containern und Kubernetes
- Container-IPs sind flüchtig: Nutze Service-Namen (K8s) oder Docker-Netzwerke.
- CoreDNS/Resolver: Prüfe
resolv.confim Pod; setze Nginxresolver. - Readiness/Liveness-Probes: Genaue Health-Endpunkte anbieten; Nginx sollte nur „ready“ Pods anfragen.
- NetworkPolicies/SecurityGroups: Freigaben zwischen Nginx-Pod und Upstream-Pods sicherstellen.
- Rolling Updates: Draining/Graceful Shutdowns, damit keine halben Responses → 502.
Monitoring, Alerting und Observability
- Metriken: 5xx-Rate, Latenzen, Upstream-Fehler, offene Verbindungen, CPU/RAM/FD.
- Logs: Korrelation von
status,upstream_response_timeundrequest_time. - Alarme: Schwellen für 502-Anteil pro Route/Service; Spike-Detection.
Praxis: Eine 502‑Rate > 1–2 % über mehrere Minuten ist ein klarer Handlungsindikator in Produktion.
Prävention: So vermeidest du 502 in der Praxis
- Konfig konsistent halten: Automatisierte Tests (
nginx -tim CI), Infrastructure as Code. - Health Checks: Streng genug, aber nicht hypersensibel; kurze fail_timeout.
- Kapazitätsmanagement: Rechtzeitig skalieren; Lasttests vor Releases.
- Robuste Timeouts/Backoffs: Für alle Ebenen (Client, Proxy, Upstream, DB, externe APIs).
- Caching/Queues: Teure Pfade gezielt entlasten.
Häufige Fehlkonfigurationen (Checkliste)
- Falscher Socket-Pfad in
fastcgi_pass, obwohl PHP-FPM auf anderem Pfad lauscht. - Nginx-User hat keine Berechtigung auf den Unix-Socket.
proxy_passzeigt auf HTTP, Upstream erwartet aber HTTPS (oder umgekehrt).- DNS-Name in
proxy_pass, aber Nginxresolverfehlt oder ist fehlerhaft. - Unrealistisch kurze
proxy_read_timeout/fastcgi_read_timeoutbei komplexen Abfragen. - Zu wenige Worker/FD-Limits → Verbindungsengpässe unter Last.
- Firewall/SecurityGroups blockieren interne Upstream-Ports.
Stack-spezifische Hinweise
PHP-FPM
- pm.*-Settings: Passe
pm.max_childrenan Traffic und RAM an. - Timeouts:
max_execution_timeundrequest_terminate_timeoutkonsistent mit Nginx setzen. - Slowlog:
request_slowlog_timeoutundslowlognutzen, um Hänger zu finden.
Node.js
- Single-threaded: Skaliere per Cluster/PM2 oder mehrere Instanzen hinter Nginx.
- Keep-Alive: Aktiviere
proxy_http_version 1.1und entferneConnection: close.
Python (Gunicorn/uWSGI)
- Worker-Anzahl: CPU-Kerne und Workload beachten (z. B.
workers = 2 * cores + 1als Startwert). - Timeouts: Gunicorn
--timeoutan reale Latenzen anpassen.
Konkrete „First Aid“-Befehle
# Services neu starten
systemctl restart nginx
systemctl restart php8.2-fpm
# Nginx-Konfig checken und reloaden
nginx -t && systemctl reload nginx
# Konnektivität testen
curl -sv http://127.0.0.1:3000/
nc -zv 127.0.0.1 9000
# Logs lesen
tail -f /var/log/nginx/error.log
journalctl -u php8.2-fpm -f
Fazit
Ein 502 in Nginx ist kein Mysterium, sondern fast immer ein konkretes Kommunikations- oder Stabilitätsproblem zwischen Proxy und Upstream. Gehe systematisch vor: Error-Logs lesen, Upstream-Status prüfen, Socket/Port/DNS/TLS verifizieren, Timeouts und Ressourcenlage checken. Korrigiere Berechtigungen, harmonisiere Konfigurationen, skaliere gezielt und setze Health Checks, Caching sowie sinnvolle Timeouts ein. Mit sauberem Monitoring und klaren Betriebsstandards hältst du die 502-Rate niedrig – und deine Plattform stabil.
FAQ
Was unterscheidet 502 von 504 konkret?
502 meldet eine ungültige oder fehlgeschlagene Antwort vom Upstream (z. B. Verbindung verweigert, TLS-Handshake scheitert). 504 ist ein reines Timeout: Der Upstream antwortet zu langsam und überschreitet das konfigurierte Limit.
Wo finde ich die entscheidenden Hinweise zur Ursache?
Im Nginx-Error-Log (/var/log/nginx/error.log) und im jeweiligen Upstream-Log. Achte auf Meldungen wie connect() failed, upstream timed out, permission denied, no live upstreams oder bad gateway while reading the response.
Wie teste ich schnell, ob der Upstream grundsätzlich erreichbar ist?
Nutze curl und nc direkt auf dem Nginx-Host: curl -sv http://127.0.0.1:3000/ oder für Sockets curl --unix-socket /run/php/php8.2-fpm.sock http://localhost/status. Für TLS openssl s_client verwenden.
Kann ein falscher DNS-Eintrag zu 502 führen?
Ja. Wenn Nginx Hostnames im proxy_pass nutzt, aber den Resolver nicht korrekt konfiguriert hat (oder DNS selbst fehlerhaft ist), schlägt die Namensauflösung fehl und resultiert in 502. Hinterlege einen stabilen resolver.
Wie gehe ich mit Timeouts um?
Setze proxy_read_timeout/fastcgi_read_timeout gemäß realer Latenzen. Prüfe parallel die Upstream-Timeouts (z. B. max_execution_time in PHP). Erhöhe nicht blind; optimiere langsame Pfade (Datenbank, externe APIs, Caching).
Wieso sehe ich 502 nur unter Last?
Wahrscheinlich kollabiert der Upstream unter Last (RAM voll, OOM-Killer, zu wenige Worker, FD-Limits erreicht). Skaliere horizontal, tune Worker/FD-Limits und setze Caching/Queueing ein. Überwache Ressourcen engmaschig.
Kann ich 502 mit einer Fallback-Seite abfedern?
Ja, per error_page 502 504 /custom_50x.html;. Das löst die Ursache nicht, verbessert aber die Nutzererfahrung und kann Telemetrie enthalten, um Fehler schneller zu erkennen.
Wie verhindere ich, dass Nginx auf einen kaputten Upstream weiterleitet?
Implementiere Health Checks (z. B. explizite /health-Endpoints) und nutze proxy_next_upstream sowie Load-Balancing mit max_fails/fail_timeout. In Microservices zusätzlich Circuit Breaker verwenden.
Spielt SSL/TLS intern zwischen Nginx und Upstream eine Rolle?
Ja. Abgelaufene Zertifikate, falsches SNI oder Protokoll-/Cipher-Mismatches führen zu 502. Prüfe mit openssl s_client und setze ggf. proxy_ssl_server_name on;.
Helfen Keep-Alive-Verbindungen?
Oft ja. Aktiviere im Upstream-Block keepalive und setze proxy_http_version 1.1 mit Connection: "". Das reduziert Verbindungsaufbaukosten und Stabilitätsprobleme unter Last.
Was ist die schnellste „Erste Hilfe“ bei 502?
Logs checken, Upstream-Status prüfen und Services neu starten. Häufig liegt es an einem abgestürzten/gestoppten Upstream oder einer frisch fehlerhaften Config. Danach strukturiert die Ursachenanalyse fortsetzen.
Wie minimiere ich 502 bei Deployments?
Nutze Blue/Green- oder Rolling-Deploys mit Graceful Shutdown und Readiness-Probes. Entferne Instanzen aus dem Pool, bevor du sie stoppst, und gib laufenden Requests Zeit, sauber zu enden.

