HTTP 502 Bad Gateway
A proxy or gateway (Nginx, load balancer, CDN) got an invalid response — or no response — from the upstream server behind it.
Meaning
With 502 the proxy is working; the app server behind it is not. Typical setups: Nginx → PHP-FPM, Nginx → Node/Gunicorn, ALB → EC2/containers, Cloudflare → origin. The upstream crashed, isn’t listening on the expected port/socket, or closed the connection mid-response.
Common causes
- Upstream app is down or crashed (PHP-FPM, Node, Gunicorn, container)
- Wrong upstream address, port or Unix socket path in proxy config
- Upstream process killed by OOM or restarted during the request
- Socket permission mismatch between Nginx and PHP-FPM
- Upstream response headers too large for proxy buffers
- Firewall/security group blocking proxy → upstream
⚡ Quick fix
- Check that the upstream service is running (
systemctl status php8.2-fpm,pm2 status,docker ps) - Verify the
proxy_pass/fastcgi_passaddress matches where the app listens - Read the proxy error log — it names the upstream error (connection refused, reset, prematurely closed)
- Restart the upstream service and watch its logs
Detailed fix by platform
Nginx
- "connect() failed (111: Connection refused)" → upstream not listening; "(13: Permission denied) while connecting to upstream" → socket permissions or SELinux.
- Match the PHP-FPM socket:nginx
location ~ \.php$ { include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass unix:/run/php/php8.2-fpm.sock; # must match listen = in www.conf } - "upstream sent too big header" → raise
proxy_buffer_size 16k; proxy_buffers 4 32k;(or fastcgi_ equivalents).
PHP
- Check
listen,listen.ownerandlisten.groupin/etc/php/8.2/fpm/pool.d/www.conf; look for "server reached pm.max_children" in the FPM log.
Node.js
- Ensure the app listens on the port Nginx proxies to and on
0.0.0.0inside containers; check for crashes inpm2 logs.
AWS
- ALB 502: check target health, that targets respond with valid HTTP, and that app keep-alive timeout is longer than the ALB idle timeout (60s).
Cloudflare
- Cloudflare-branded 502 means the origin returned an invalid response; check origin logs, or see 520–526 for specific edge errors.
Code examples
Quick upstream checks
bash
sudo tail -n 30 /var/log/nginx/error.log
sudo ss -ltnp | grep -E ':(3000|8000|9000)'
ls -l /run/php/
curl -I http://127.0.0.1:3000/ # hit the upstream directly, bypassing NginxHow to diagnose
- Proxy log — What upstream error does Nginx/LB report?
- Upstream process — Running? Recently restarted or OOM-killed?
- Address — Port/socket in config matches where the app listens?
- Direct test — Does the upstream answer when called directly?
- Network — Firewall/security groups between proxy and upstream?
🧠 Still stuck? Analyze your error
Paste the full message, response headers or stack trace — we'll detect the platform and point to the most likely cause.
Was this page helpful?
Report a correction or suggest an improvement
Last updated 2 Oct 2026