Nginx connection errors, such as “502 Bad Gateway,” “connection refused,” or “upstream timed out,” usually stem from misconfigured proxy settings, exhausted server resources, or firewall rules. This article explains the most frequent nginx connection problems and provides step-by-step fixes you can apply to your configuration and server.
Background: Why Nginx Connection Errors Happen
Nginx is a high-performance web server and reverse proxy. When it cannot establish or maintain a connection to a backend server (like PHP-FPM, Node.js, or another nginx instance), it returns an error to the client. These errors are not random; they almost always trace back to one of a few root causes: incorrect upstream addresses, timeouts that are too short, or system limits on file descriptors and connections.
Understanding the difference between a client-facing error and a server-side log message helps. For example, a “502 Bad Gateway” appears when nginx receives an invalid response from the upstream, while “504 Gateway Timeout” means the upstream took too long. Checking the nginx error log (/var/log/nginx/error.log) is the first diagnostic step for any of these issues.
How Nginx Handles Connections
Nginx uses an event-driven, asynchronous architecture. Instead of spawning a thread or process per connection, it handles thousands of connections within a single worker process using non-blocking I/O. This design is efficient, but it also means that certain misconfigurations can cause widespread failures.
When a client requests a page, nginx either serves a static file directly or proxies the request to an upstream server defined in an upstream block or via proxy_pass. The connection between nginx and the upstream is a separate TCP connection, and it is this connection that most error messages refer to. If the upstream is down, unreachable, or too slow, nginx cannot complete the request.
Common Connection Errors and Their Fixes
1. 502 Bad Gateway
This error means nginx received an invalid response from the upstream server. The most common causes are:
- The backend service (e.g., PHP-FPM, Gunicorn) is not running.
- The backend is listening on the wrong socket or port.
- Firewall rules block the connection between nginx and the backend.
How to fix:
- Verify the backend process is running:
systemctl status php7.4-fpm(or your service name). - Check the socket path in your nginx config matches the one in the backend config. For PHP-FPM, look in
/etc/php/7.4/fpm/pool.d/www.confforlisten = /run/php/php7.4-fpm.sockand compare withfastcgi_pass unix:/run/php/php7.4-fpm.sock;in your nginx site config. - Test firewall rules:
sudo ufw statusoriptables -L. Ensure the port used by the backend (e.g., 9000) is open only for localhost if it’s on the same machine.
2. 504 Gateway Timeout
Nginx waited too long for the upstream to respond. This often happens with slow database queries or external API calls.
How to fix:
- Increase the
proxy_read_timeoutin the location block. For example:proxy_read_timeout 300s; - For FastCGI (PHP), use
fastcgi_read_timeout 300s; - If the backend is genuinely slow, consider optimizing the application or database query instead of just raising the timeout.
3. Connection Refused
This error appears in the nginx error log as connect() failed (111: Connection refused). It means the TCP connection to the upstream was actively rejected. Causes include:
- The backend is not listening on the expected IP/port.
- The backend is listening on IPv6 (::1) but nginx is trying IPv4 (127.0.0.1) or vice versa.
- SELinux or AppArmor is blocking the connection.
How to fix:
- Confirm the backend’s listening address with
ss -tlnpornetstat -tlnp. - Match the
proxy_passURL exactly. For example, if the backend listens on127.0.0.1:3000, useproxy_pass http://127.0.0.1:3000;. - If using SELinux, check audit logs (
ausearch -m avc) and allow the connection if needed.
4. Upstream Sent Too Big Header
When the backend response headers exceed nginx’s buffer size, you see this error. It’s common with applications that set many cookies or use large authentication tokens.
How to fix:
- Increase
proxy_buffer_sizeandproxy_buffersin the nginx config. - Example:
proxy_buffer_size 8k;andproxy_buffers 8 8k;. - Alternatively, reduce the size of cookies or headers in the application.
Diagnosing with Logs and Commands
Nginx logs are your best friend. The error log location is usually /var/log/nginx/error.log, but it can be set in the main nginx.conf with the error_log directive. The access log (/var/log/nginx/access.log) shows which requests returned 5xx errors.
Useful commands:
nginx -tto test the configuration for syntax errors.tail -f /var/log/nginx/error.logto watch errors in real time while reproducing the issue.curl -I http://localhostto test the site from the server itself, bypassing external firewalls.
Resource Limits: File Descriptors and Worker Connections
Even with correct configuration, nginx can fail to accept new connections if it hits system limits. The key parameters are:
worker_connectionsinnginx.conf– the maximum number of simultaneous connections per worker process.worker_rlimit_nofile– the maximum number of file descriptors nginx can open.- The system-wide limit set by
ulimit -n.
If you see too many open files in the error log, raise these limits. For example, set worker_rlimit_nofile 65535; and increase the system limit in /etc/security/limits.conf.
Also, the operating system’s net.core.somaxconn and net.ipv4.tcp_max_syn_backlog control the listen queue. If the queue is full, clients may see connection resets. Increase these in /etc/sysctl.conf and apply with sysctl -p.
Common Misconception: It’s Always a Firewall Issue
Many users immediately suspect firewalls when they see connection errors, but often the problem is simpler. For example, a typo in the proxy_pass URL (like using http://localhost:3000 when the backend listens on 127.0.0.1:3000 but only on IPv4) can cause a connection refused. Always check the backend first: is it running? Is it listening on the expected address? Only then move to firewall rules.
Another misconception is that increasing timeouts always fixes slow responses. If the backend is overloaded, longer timeouts just make users wait longer. Monitor the backend’s CPU and memory usage to see if it’s the bottleneck.
Frequently Asked Questions
Why do I get a 502 error even though the backend is running?
This often happens when the backend is listening on a different socket or port than what nginx expects. Check both configurations carefully. Also, ensure the backend process has permission to write to the socket file if using Unix sockets.
How do I increase the timeout for a specific location only?
You can place proxy_read_timeout inside a location block. For example, for a slow API endpoint, create a location block with a higher timeout value than the rest of the site.
What does “upstream prematurely closed connection” mean?
This means the backend closed the TCP connection before sending a complete response. Common causes include the backend crashing, a timeout in the backend itself, or the backend’s keep-alive settings being too aggressive. Check the backend’s logs for errors.
Can I use nginx as a load balancer to avoid connection errors?
Yes, nginx can distribute traffic across multiple upstream servers. If one server fails, nginx can retry the request on another server (if configured with proxy_next_upstream). However, this does not fix the root cause if all backends have the same issue.
Why does nginx return 502 after I restart the backend?
There might be a brief period where nginx still has keep-alive connections to the old backend process. These stale connections cause 502 errors. Restarting nginx or waiting a few seconds usually resolves it. To avoid this, use a socket file and ensure the backend gracefully handles old connections.
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
- Google Assistant IFTTT Recipes: 7 Useful Automations
- OLED TVs in Dark Rooms: Why They Look Better and When They Don’t
- Philips DST7060/20 7000 Series Iron: Specs & Fit
- Coal Fueled Jet Aircraft: Could It Work?675 L
- Remote Desktop on Raspberry Pi: How to Enable It
- Word Select Last Line in Paragraph?