Nginx Reverse Proxy Checklist
Nginx problems often show up as API 502 errors, broken redirects, missing headers, CORS failures, HTTPS loops or static files served from the wrong location. The Nginx beginner guide covers the basic service and configuration model at nginx.org/en/docs/beginners_guide.html. This Formalint checklist is for the operational debugging path.
Config and service identity
nginx -v
nginx -V 2>&1 | tr ' ' '\n' | grep -- '--conf-path'
nginx -t
systemctl status nginx --no-pager
journalctl -u nginx -n 120 --no-pagerFind active server blocks
Before editing, identify which file is actually loaded. Many failures come from changing a file that is not included by the active Nginx config.
nginx -T 2>/tmp/nginx-rendered.conf
grep -n "server_name\\|proxy_pass\\|listen\\|root\\|location" /tmp/nginx-rendered.conf | head -120
ls -la /etc/nginx/sites-enabled 2>/dev/null
ls -la /etc/nginx/conf.d 2>/dev/nullProxy and upstream checks
ss -tulpn | grep -E ':80|:443|:3000|:5000|:8000|:8080'
curl -I http://127.0.0.1:3000/health
curl -I http://127.0.0.1:8000/health
curl -I https://example.com/
curl -I -H "Host: example.com" http://127.0.0.1/Headers and API forwarding
APIs often need the original host, scheme and client IP. Missing proxy headers can break redirects, callback URLs, authentication and logs.
location /api/ {
proxy_pass http://127.0.0.1:3000/;
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;
}Common Nginx proxy failures
| Symptom | Check first | Likely direction |
|---|---|---|
| 502 Bad Gateway | Upstream port, app process, error log | Nginx cannot reach the application service. |
| Redirect loop | X-Forwarded-Proto, app trusted proxy settings | The app thinks HTTPS requests are HTTP. |
| CORS failure | Response headers, preflight route, API app config | The browser blocks a response that curl can still fetch. |
| Wrong site served | server_name, listen order, default server | The request matches a different server block. |
| Large upload fails | client_max_body_size, app upload limit | Nginx rejects the request before the app sees it. |
TLS and certificate checks
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null | openssl x509 -noout -dates -subject -issuer
curl -I https://example.com/
grep -n "ssl_certificate\\|ssl_certificate_key" /tmp/nginx-rendered.conf
nginx -tLog-focused debugging
tail -n 120 /var/log/nginx/error.log
tail -n 120 /var/log/nginx/access.log
grep " 502 " /var/log/nginx/access.log | tail -30
grep "upstream" /var/log/nginx/error.log | tail -30Safe reload order
nginx -t
systemctl reload nginx
systemctl status nginx --no-pager
curl -I https://example.com/
tail -n 40 /var/log/nginx/error.logA good Nginx fix proves four things: the active config file, the matching server block, the reachable upstream and the response headers the browser actually receives.
Related: HTTP Headers Reference, API Debugging Checklist, Docker Compose Debugging.