Nginx 502·504 Difference
Nginx is a lightweight, high-performance open-source Web Server.
Initially, it started as a web server serving static files like HTML and images, but now it's used as infrastructure software performing roles such as reverse proxy, load balancer, and HTTP cache.
- Event-driven Architecture: Unlike traditional web servers like Apache, which allocate one thread/process per request, Nginx has an asynchronous event-driven structure. It can handle numerous concurrent connections with minimal memory.
- Reverse Proxy: It acts as a gatekeeper, not directly processing client requests but forwarding them to the backend application server, receiving the results, and then passing them back to the client.
Difference between 502 Bad Gateway vs 504 Gateway Timeout #
Both of these errors occur during communication between Nginx and the backend server when Nginx operates as a reverse proxy. They share the commonality that they arise not from Nginx itself, but from the state of the backend server Nginx is pointing to, but their causes are distinctly different.
502 Bad Gateway (Bad Response) #
This occurs when Nginx sends a request to the backend server but receives an invalid response or cannot establish a connection at all. In other words, the backend server is down or unreachable.
- Main Causes
- The backend application (e.g., Tomcat, Node.js) process has died and is down.
- Incorrect port or IP address for the backend server in the Nginx configuration (nginx.conf).
- The backend server is receiving too much traffic and can no longer establish connections.
504 Gateway Timeout #
This occurs when Nginx sends a request to the backend server and successfully establishes a connection, but the backend server fails to respond within the specified time.
Nginx decides it has waited long enough and returns a 504 to the client.
- Main Causes
- The logic running on the backend server, such as complex database queries or infinite loops, takes too long, resulting in a timeout.
- Calls to external APIs that the backend server depends on are delayed.
- The Nginx proxy timeout setting
proxy_read_timeoutis set too short.
In summary, a 502 means Nginx couldn't even connect to the backend server due to communication failure or an abnormal response state. Solutions include restarting the backend process, checking ports, or inspecting firewalls.
A 504 indicates a timeout because the backend server's response was too slow; the connection was successful, but Nginx gave up waiting for a response. Approaches to resolve this include tuning backend logic performance or increasing Nginx timeouts.
Nginx Proxy Configuration Example (nginx.conf or default.conf) #
This is the configuration file structure used when 504 errors frequently occur, requiring an increase in wait times, or when checking backend settings to prevent 502 errors.
http {
# Define backend server group (check IP/Port here if 502 error occurs)
upstream backend_servers {
server 127.0.0.1:8080; # e.g., Spring Boot or Node.js port
}
server {
listen 80;
server_name mywebsite.com;
location /api/ {
# Reverse proxy settings
proxy_pass http://backend_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# Timeout settings to prevent 504 Gateway Timeout (default is usually 60s)
proxy_connect_timeout 90s; # Time to wait for a connection to the backend
proxy_send_timeout 90s; # Time to wait for sending a request to the backend
proxy_read_timeout 120s; # Time to wait for reading a response from the backend (important!)
}
}
}
Let's also look into approaches for identifying the cause. Here are commands you can use immediately in the server terminal when an error occurs to pinpoint its origin.
# First, check Nginx logs
tail -f /var/log/nginx/error.log
# 502 example
[error] 1234#0: *5678 connect() failed (111: Connection refused) while connecting to upstream, client: 192.168.1.10, server: mywebsite.com, request: "GET /api/data HTTP/1.1", upstream: "http://127.0.0.1:8080/api/data"
# 504 example
[error] 1234#0: *5679 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 192.168.1.10, server: mywebsite.com, request: "GET /api/heavy-job HTTP/1.1", upstream: "http://127.0.0.1:8080/api/heavy-job"
It's also good to check the port.
# Check if port 8080 is open and listening normally
netstat -tulpn | grep 8080
# or
ss -tulpn | grep 8080
tcp 0 0 127.0.0.1:8080 0.0.0.0:* LISTEN 5432/java
If the result appears as above, it's normal; if nothing shows up, the backend server is down.