Introduction
After making changes to your Nginx configuration, you receive a 502 Bad Gateway error when accessing your site. Nginx is running, but it cannot successfully communicate with the upstream server (application server, PHP-FPM, another proxy, etc.). The configuration change likely broke the connection to the backend.
Symptoms
```bash $ curl -I http://localhost HTTP/1.1 502 Bad Gateway
$ tail -f /var/log/nginx/error.log 2024/01/01 12:00:00 [error] connect() failed (111: Connection refused) while connecting to upstream 2024/01/01 12:00:00 [error] upstream prematurely closed connection while reading response header
$ curl http://localhost/api <html> <head><title>502 Bad Gateway</title></head> <body> <center><h1>502 Bad Gateway</h1></center> <hr><center>nginx</center> </body> </html>
# Browser shows: # 502 Bad Gateway # nginx ```
Common Causes
- 1.Upstream server not running: Backend service crashed or stopped
- 2.Wrong upstream address: Incorrect host or port in proxy_pass
- 3.Firewall blocking: Network rules preventing connection
- 4.PHP-FPM socket issues: Socket file missing or permissions wrong
- 5.Upstream timeout: Backend taking too long to respond
- 6.Connection limit exceeded: Too many connections to upstream
- 7.DNS resolution failure: Cannot resolve upstream hostname
- 8.Protocol mismatch: HTTP vs HTTPS mismatch
Step-by-Step Fix
- 1.Check logs for specific error messages
- 2.Verify configuration settings
- 3.Test network connectivity
- 4.Review recent changes
- 5.Apply corrective action
- 6.Verify the fix
Step 1: Check Upstream Server Status
Verify the backend is running:
```bash # Check if upstream service is running # For PHP-FPM systemctl status php-fpm service php-fpm status
# For Node.js/app server ps aux | grep node netstat -tulpn | grep :3000
# For generic upstream curl -v http://backend-server:8080 curl -v http://localhost:3000
# Check port connectivity nc -zv backend-server 8080 telnet backend-server 8080
# For Unix socket upstream ls -la /var/run/php/php-fpm.sock # Socket should exist and be readable ```
Step 2: Verify Nginx Upstream Configuration
Check proxy_pass settings:
```bash # View upstream configuration grep -r "upstream" /etc/nginx/ grep -r "proxy_pass" /etc/nginx/
# Check specific server block cat /etc/nginx/sites-enabled/default | grep -A 20 "location" ```
Correct upstream configuration: ```nginx # For HTTP upstream upstream backend { server 127.0.0.1:3000; # Or with keepalive server 127.0.0.1:3000 max_fails=3 fail_timeout=30s; keepalive 32; }
server { location / { proxy_pass http://backend; proxy_http_version 1.1; proxy_set_header Connection ""; } }
# For PHP-FPM (socket) location ~ \.php$ { fastcgi_pass unix:/var/run/php/php-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; }
# For PHP-FPM (TCP) location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; } ```
Step 3: Fix Wrong Upstream Address
Correct the upstream address:
```bash # Find the actual port your app is running on netstat -tulpn | grep LISTEN ss -tulpn | grep LISTEN
# Update nginx configuration sudo nano /etc/nginx/sites-enabled/default ```
```nginx # If app runs on port 3000, make sure proxy_pass matches location / { proxy_pass http://127.0.0.1:3000; # Correct port }
# Check if using upstream block upstream myapp { server 127.0.0.1:3000; # Must match actual app port } ```
# Test and reload
sudo nginx -t
sudo systemctl reload nginxStep 4: Fix PHP-FPM Socket Issues
For PHP-FPM 502 errors:
```bash # Check PHP-FPM status systemctl status php-fpm
# Check socket file ls -la /var/run/php/ # Should show php-fpm.sock or similar
# Check socket permissions ls -la /var/run/php/php-fpm.sock # Should be readable by nginx user
# Fix permissions sudo chmod 666 /var/run/php/php-fpm.sock # Or add nginx to the right group sudo usermod -a -G www-data nginx
# If socket doesn't exist, check pool config cat /etc/php/8.x/fpm/pool.d/www.conf | grep listen # listen = /run/php/php-fpm.sock
# Alternative: use TCP instead of socket # In php-fpm pool config: listen = 127.0.0.1:9000
# In nginx: fastcgi_pass 127.0.0.1:9000; ```
Step 5: Check Firewall and Network
Verify network connectivity:
```bash # Test direct connection to upstream curl -I http://127.0.0.1:3000 curl -I http://backend-server:8080
# Check firewall rules sudo iptables -L -n | grep 3000 sudo firewall-cmd --list-all
# Allow port if blocked sudo firewall-cmd --add-port=3000/tcp --permanent sudo firewall-cmd --reload
# Or iptables sudo iptables -A INPUT -p tcp --dport 3000 -j ACCEPT
# Check SELinux (CentOS/RHEL) getenforce sudo setsebool -P httpd_can_network_connect 1 ```
Step 6: Adjust Timeout Settings
Increase timeouts if upstream is slow:
```nginx location / { proxy_pass http://backend;
# Timeout settings proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s;
# For long-running requests proxy_read_timeout 300s;
# Send timeouts send_timeout 60s;
# Buffer settings proxy_buffering on; proxy_buffer_size 4k; proxy_buffers 8 4k; } ```
Step 7: Configure Upstream Health Checks
Add health monitoring:
```nginx upstream backend { server 127.0.0.1:3000 max_fails=3 fail_timeout=30s; server 127.0.0.1:3001 backup;
# Health check (requires nginx plus or module) # health_check interval=5s fails=3 passes=2; }
server { location / { proxy_pass http://backend; proxy_next_upstream error timeout http_502 http_503 http_504; proxy_next_upstream_tries 3; } } ```
Step 8: Enable Debug Logging
Debug the 502 error:
# Enable debug logging
error_log /var/log/nginx/error.log debug;```bash # Reload nginx sudo systemctl reload nginx
# Watch debug logs tail -f /var/log/nginx/error.log
# Look for: # connect() to upstream # upstream response # connection state ```
Step 9: Check Connection Limits
Verify connection limits:
```bash # Check worker connections grep worker_connections /etc/nginx/nginx.conf # Default is often 1024, increase if needed: # worker_connections 4096;
# Check upstream connections ss -tnp | grep nginx | wc -l
# Check file descriptor limits ulimit -n # Should be >= worker_connections
# Increase limits sudo nano /etc/security/limits.conf ```
Add:
``
nginx soft nofile 65535
nginx hard nofile 65535
Step 10: Test Upstream Directly
Bypass Nginx to test backend:
```bash # Test backend directly curl -v http://127.0.0.1:3000/api/test curl -v http://backend-server:8080/health
# Check response time time curl http://127.0.0.1:3000/large-response
# Test with same headers as Nginx curl -H "Host: example.com" http://127.0.0.1:3000/
# For PHP-FPM, test with cgi-fcgi cgi-fcgi -bind -connect /var/run/php/php-fpm.sock
# Or test PHP directly php -r "echo 'PHP works';" ```
Verification
Confirm 502 is resolved:
```bash # Test Nginx endpoint curl -I http://localhost # Should return HTTP 200
# Check upstream connectivity curl -I http://localhost/api # Should return proper response
# Monitor logs for errors tail -f /var/log/nginx/error.log | grep -v "debug"
# Check backend status systemctl status php-fpm ps aux | grep node
# Verify configuration sudo nginx -t # Should show: syntax is ok, test is successful
# Test multiple requests for i in {1..10}; do curl -s -o /dev/null -w "%{http_code}\n" http://localhost; done # All should be 200 ```
The 502 Bad Gateway should be resolved and responses should return HTTP 200.
Related Articles
- [Nginx troubleshooting: Fix Lambda Permission Denied - Complete ](fix-lambda-permission-denied)
- [Nginx web server troubleshooting: Fix Client Max Body Size Large Upload Nginx Issue ](client-max-body-size-large-upload-nginx)
- [Fix Apache 502 Proxy Error](fix-apache-502-proxy-error)
- [Fix Apache LogLevel Core Debug Configuration](fix-apache-loglevel-core-debug)
- [Fix Cloudflare 502 Bad Gateway Error](fix-cloudflare-502-bad-gateway)
<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "Nginx 502 Bad Gateway After Config", "description": "Resolve Nginx 502 Bad Gateway errors with upstream checks, proxy configuration, and timeout settings", "url": "https://www.fixwikihub.com/fix-nginx-502-bad-gateway-upstream", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2025-11-19T08:12:04.845Z", "dateModified": "2025-11-19T08:12:04.845Z" } </script>