What 502 and 504 mean
A 502 Bad Gateway means Nginx connected to the application but got no valid answer, or could not connect at all. A 504 Gateway Timeout means Nginx waited longer than its timeout for the application to respond. In both cases Nginx is working, and the problem is between Nginx and the application behind it.
Always read the Nginx error log before changing anything. It names the exact cause.
sudo tail -n 30 /var/log/nginx/error.log
sudo nginx -tRead the error message
Look for the upstream message. "connect() failed (111: Connection refused) while connecting to upstream" means nothing is listening where Nginx is looking. "(13: Permission denied)" points to socket permissions or SELinux. "upstream timed out (110: Connection timed out)" is a 504, where the application is too slow or hung. "no live upstreams" means every configured backend is marked down. "upstream prematurely closed connection" means the application crashed or reset the connection.
Find what Nginx is pointing at
Show the effective configuration for your site and find the proxy_pass or fastcgi_pass line. Note the address and port or socket path exactly. A mismatch between that and where the application actually listens is the most common cause.
sudo nginx -T 2>/dev/null | grep -nE "server_name|proxy_pass|fastcgi_pass|upstream"Check the application is running and listening
Check that the service is active and that something listens on the expected port. If the app is not running, read its logs for the reason. If it listens on a different port or on a different address, such as only an IPv6 address, correct one side. Bind the app to 127.0.0.1 when Nginx proxies to 127.0.0.1.
sudo systemctl status myapp --no-pager
sudo ss -lntp | grep -E ":(3000|8080|8000)\b"
sudo journalctl -u myapp --since "30 minutes ago" --no-pager | tail -n 30curl -sv http://127.0.0.1:3000/ -o /dev/null 2>&1 | head -n 15PHP-FPM and sockets
For PHP sites, a 502 often means PHP-FPM is stopped or Nginx cannot use its socket. Check the service and the socket file, and make sure the path in fastcgi_pass matches. The socket must be accessible to the Nginx user.
systemctl status php8.3-fpm --no-pager
ls -l /run/php/systemctl status php-fpm --no-pager
ls -l /run/php-fpm/SELinux on AlmaLinux
If the application runs and answers locally but Nginx still reports permission denied, SELinux is probably blocking Nginx from connecting out. Check for recent denials, and enable the network connection permission rather than disabling SELinux.
sudo ausearch -m avc -ts recent | tail -n 10
getsebool httpd_can_network_connect
sudo setsebool -P httpd_can_network_connect 1Timeouts and slow applications
A 504 means the application is slow or stuck. Test how long the application takes with curl directly, and check CPU, memory and database load at that moment, as in the slow VPS guide. If a request legitimately takes long, such as an upload or report, raise the Nginx timeouts for that location, but fixing the slow code or query is the better answer.
curl -o /dev/null -s -w "connect %{time_connect}s first byte %{time_starttransfer}s total %{time_total}s\n" http://127.0.0.1:3000/proxy_connect_timeout 10s;
proxy_read_timeout 120s;
proxy_send_timeout 120s;Containers, big headers and uploads
If the backend is a Docker container, check that the port is published on 127.0.0.1 and that the container is healthy. An error with large cookies or headers can show as a 502, which needs larger proxy buffers. Large uploads fail with 413, which needs client_max_body_size. After any change, test and reload.
sudo docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
sudo nginx -t && sudo systemctl reload nginx
curl -I https://example.com/Official documentation
These upstream references provide more detail on the commands and workflows in this guide.