This guide walks you through diagnosing and fixing a 502 Bad Gateway error in an Nginx reverse proxy setup. You’ll learn the common causes—from upstream server downtime to misconfigured proxy settings—and how to resolve each one with clear, actionable steps. No prior Nginx expertise is required, but basic command-line familiarity helps.
What You’ll Need
- Access to the server running Nginx (SSH or terminal).
- sudo or root privileges to edit configuration files and restart services.
- The address and port of your upstream application (e.g., localhost:3000 or 127.0.0.1:8080).
- A text editor like nano or vim installed on the server.
Step-by-Step
- Confirm the error source. Open a browser and visit your site. If you see a plain 502 Bad Gateway page, the issue is server-side. Use
curl -I http://your-domain.comfrom your local machine to see the HTTP status code and headers. A 502 means Nginx received an invalid response from the upstream server. - Check if the upstream application is running. SSH into your server and run
sudo systemctl status your-app-service(replace with your actual service name). If it’s not active, start it withsudo systemctl start your-app-service. For non-systemd setups, useps aux | grep your-appto see if the process exists. If the app isn’t running, that’s the root cause—fix the app and restart it. - Test the upstream directly. From the Nginx server, run
curl http://127.0.0.1:3000(replace with your upstream address). If you get a response, the app is reachable. If you get a connection refused or timeout, the app is either not listening on that port or is bound to a different interface (e.g., only on localhost vs. all interfaces). Adjust the app’s bind address accordingly. - Inspect Nginx error logs. Run
sudo tail -f /var/log/nginx/error.logand then trigger the 502 by visiting your site. Look for lines containing “upstream” or “connect() failed”. Common messages: “connect() failed (111: Connection refused) while connecting to upstream” or “connect() failed (110: Connection timed out)”. These tell you exactly what Nginx is trying to reach and why it fails. - Verify the proxy_pass directive. Open your Nginx site configuration (usually in
/etc/nginx/sites-available/or/etc/nginx/conf.d/). Check thelocationblock that handles your requests. Ensure theproxy_passURL matches the actual address and port of your upstream. For example, if your app runs on port 3000, it should beproxy_pass http://127.0.0.1:3000;. A common mistake is using a hostname that doesn’t resolve or a port that’s incorrect. - Check for socket file issues. If your upstream uses a Unix socket (e.g., PHP-FPM or Gunicorn), the
proxy_passmight look likeproxy_pass http://unix:/var/run/php-fpm.sock;. Verify the socket file exists withls -la /var/run/php-fpm.sock. If it’s missing, the service may not have created it—restart the service. Also ensure the Nginx user (usuallywww-data) has read/write permissions on that socket file. - Review upstream server block. If you have an
upstreamblock defined, verify the server addresses inside it. For example:upstream backend { server 127.0.0.1:3000; }Then
proxy_pass http://backend;. Make sure the server IP and port are correct and that the upstream server is actually listening on that port. - Check firewall and network rules. If the upstream is on a different machine, ensure that the Nginx server can reach it. Use
telnet upstream-ip 3000ornc -zv upstream-ip 3000to test connectivity. If it fails, check firewall rules (ufw, iptables) on both servers. Allow traffic on the required port. - Test Nginx configuration and reload. After any changes, run
sudo nginx -tto test the configuration syntax. If it says “syntax is ok”, reload Nginx withsudo systemctl reload nginx(orsudo nginx -s reload). Then test your site again. - Look for resource exhaustion. If the upstream is running but slow, check its logs for errors, and monitor system resources with
toporhtop. A 502 can occur if the upstream process crashes under load. Increase timeouts in Nginx (e.g.,proxy_read_timeout 60s;) if the app takes long to respond, but first fix the underlying performance issue.
Common Mistakes
- Using
localhostinproxy_passwhen the app is bound to a specific IP. If the app listens on 127.0.0.1, use that. If it listens on 0.0.0.0, you can use localhost, but be consistent. - Forgetting to restart the upstream application after a code change that causes it to crash.
- Editing the wrong Nginx config file—there may be multiple site configs; ensure you’re editing the one that serves your domain.
- Not checking the error log after making changes—the log will quickly tell you if the problem persists.
- Overlooking the fact that a 502 can also come from a misconfigured
proxy_set_headerthat causes the upstream to reject the request.
Tips
- Use
curl -v http://your-domain.comto see the full request/response cycle, including which server responds. - Set up a simple health check endpoint in your app (e.g.,
/health) that returns 200 OK. Then configure Nginx to monitor it, but for now use it manually to test. - Keep your Nginx config in a version control system (like Git) so you can revert changes easily.
- Add
proxy_connect_timeout 5s;to fail fast instead of hanging for the default 60 seconds. - If using Docker, ensure the upstream container is on the same Docker network and the port is published correctly.
Troubleshooting
If the above steps don’t resolve the issue:
- Check if the 502 is intermittent. If it happens randomly, it could be a timeout issue. Increase
proxy_read_timeoutandproxy_send_timeoutin the location block. - Look at the upstream application’s logs. Often the app itself logs why it failed to respond. Check
/var/log/your-app/or the app’s stdout/stderr if it’s a systemd service. - Test with a simple static file. Temporarily change the location block to serve a static file (e.g.,
root /var/www/html;) to see if Nginx itself works. If static files load, the issue is definitely with the upstream connection. - Use
straceon the Nginx worker process to see the exact syscalls being made when connecting to the upstream. This is advanced but can reveal permission issues or network problems. - Check SELinux/AppArmor. On some distributions, SELinux or AppArmor may block Nginx from making outbound connections. Check audit logs with
sudo ausearch -m avc -ts recentorsudo cat /var/log/syslog | grep DENIED. - Verify DNS resolution. If your
proxy_passuses a domain name, ensure it resolves correctly from the Nginx server. Usedig your-upstream-domain.comto check.
Frequently Asked Questions
What exactly does a 502 Bad Gateway mean?
It means Nginx, acting as a reverse proxy, did not receive a valid HTTP response from the upstream server. The upstream could be down, unreachable, or returned an invalid response.
Can a 502 be caused by a firewall?
Yes, if the upstream server is on a different host and a firewall blocks the port Nginx uses to connect, Nginx will get a connection timeout or refused, resulting in a 502.
Why does my 502 only happen on certain pages?
This often indicates that the upstream application crashes or times out when processing specific requests, such as those that are resource-intensive or trigger a bug. Check the app logs for those endpoints.
How do I fix a 502 when using PHP-FPM?
Check that the PHP-FPM service is running and that the socket file exists. Also verify the fastcgi_pass directive points to the correct socket or port, and that the socket permissions allow the Nginx user to access it.
Is a 502 the same as a 504 Gateway Timeout?
No. A 502 means the upstream returned an invalid response, while a 504 means the upstream did not respond in time. A 504 is usually fixed by increasing timeouts, while a 502 often requires fixing the upstream itself.
Can I prevent 502 errors by adding more Nginx workers?
No, adding Nginx workers won’t help if the upstream is down. It might help if the upstream is overwhelmed and slow, but the real fix is to scale the upstream application or optimize its performance.
Related
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.
More cards in this drawer
- Campus Tech Innovation Hubs: What They Are
- Poco C51 Airtel Prepaid Locked Variant India?
- Jenkins vs GitHub Actions: Which CI/CD Fits Your Team?
- Turn Off Backup Encryption in iTunes?
- Shared VPS Hosting: Is It Better?
- Disk Defrag Pro: What It Does and Whether You Need It