Troubleshooting Common Issues
1. Resolving 502 Bad Gateway
| Error Code | Description | Common Causes | Solution |
|---|---|---|---|
| 502 Bad Gateway | Server received an invalid response from upstream server |
|
|
Example: Nginx config with timeout adjustments
location /api/ {
proxy_pass http://backend;
proxy_connect_timeout 30s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
}
Note: 502 errors often occur when the backend server is unresponsive or misconfigured. Ensure that your application server (e.g., Node.js, Python Flask) is running and accessible from Nginx.
2. Fixing 504 Gateway Timeout
| Issue | Solution | Notes |
|---|---|---|
| 504 Gateway Timeout | Adjust proxy timeouts in Nginx configuration | Occurs when Nginx acts as a reverse proxy and the upstream server does not respond within the timeout period |
Example: Increasing proxy timeout values
location / {
proxy_pass http://backend;
proxy_connect_timeout 30s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
}
Note: The
proxy_read_timeout setting controls how long Nginx waits for a response from the backend server. Increasing this value can resolve 504 errors caused by slow upstream servers.
3. Debugging 413 Request Entity Too Large
| Issue | Description | Solution |
|---|---|---|
| client_max_body_size | Default limit is 1MB. Exceeding this causes 413 error. | Adjust in nginx.conf or server block. |
Example: Increasing body size limit
server {
listen 80;
server_name example.com;
client_max_body_size 20M;
}
Note: The limit can be set per location or globally.
Warning: Setting too high may cause memory issues or denial of service.
4. Resolving Configuration Conflicts
| Conflict Type | Description | Solution |
|---|---|---|
| Duplicate server blocks | Multiple server blocks with same listen address and port |
Combine or remove duplicates; ensure unique listen directives |
| Overlapping location blocks | Multiple location directives match same URI |
Use = for exact matches or ^~ to prioritize prefix matching |
| Inherited directive conflicts | Directive in http block overrides server or location block |
Explicitly override in child blocks or use include to manage inheritance |
Example: Resolving Duplicate Server Blocks
# Before: Conflicting server blocks
server {
listen 80;
server_name example.com;
root /var/www/example;
}
server {
listen 80;
server_name example.com;
root /var/www/example2;
}
# After: Merged server block
server {
listen 80;
server_name example.com;
root /var/www/example;
location / {
try_files $uri $uri/ =404;
}
}
Note: Use
nginx -t to test configuration before reloading.
Warning: Incorrectly merged blocks may lead to unexpected behavior or 404 errors.
5. Fixing Permission Denied Errors
| Error Type | Description | Solution |
|---|---|---|
| 403 Forbidden | Access to a resource is denied due to insufficient permissions. | Check file and directory permissions using ls -l. Ensure the Nginx user (usually nginx or www-data) has read access to the file. |
| 404 Not Found | Resource not found, often due to incorrect paths or permissions. | Verify the file path in nginx.conf. Ensure that the directory and file permissions allow Nginx to read the content. |
| 502 Bad Gateway | Proxying fails due to permission or access issues. | Check proxy configuration and ensure the backend server allows connections from Nginx. Validate that the user running Nginx has access to the backend. |
Example: Setting Correct Permissions
sudo chown -R nginx:nginx /var/www/html
sudo chmod -R 755 /var/www/html
Note: Ensure that the Nginx user has read access to all files and directories it needs to serve. If using a custom user, make sure the user is added to the appropriate group.
Warning: Avoid setting overly permissive permissions (e.g., 777) as this can introduce security vulnerabilities.
6. Debugging SSL Handshake Failures
| Issue | Description | Solution |
|---|---|---|
| SSL handshake timeout | Client fails to complete SSL handshake within timeout period. | Check network connectivity and increase proxy_connect_timeout or ssl_handshake_timeout. |
| SSL certificate mismatch | Server certificate does not match the requested domain. | Verify server_name directive matches certificate CN or SAN. |
| Incompatible SSL/TLS versions | Client and server do not support a common TLS version. | Ensure ssl_protocols includes supported versions like TLSv1.2 TLSv1.3. |
| Missing intermediate certificate | Client cannot build a trust chain to root CA. | Ensure ssl_trusted_certificate includes intermediate certs. |
Example: Enabling SSL debug logging
error_log /var/log/nginx/error.log debug;
server {
listen 443 ssl;
ssl_certificate /etc/ssl/certs/nginx.crt;
ssl_certificate_key /etc/ssl/private/nginx.key;
# Enable detailed SSL handshake logs
ssl_debug on;
}
Note: Use
ssl_debug on; only in testing environments as it may expose sensitive data.
7. Resolving DNS Resolution Issues
| Issue | Description | Solution |
|---|---|---|
| DNS resolution fails | Requests to domains fail due to DNS lookup errors. | Check resolver directive in Nginx config. Ensure DNS servers are reachable. |
| Timeout during DNS lookup | Requests hang or timeout waiting for DNS resolution. | Adjust resolver_timeout to allow more time for DNS resolution. |
| Incorrect upstream domain | Upstream server name is misspelled or invalid. | Verify domain names in upstream blocks and proxy_pass. |
Note: Using public DNS servers like Google's (8.8.8.8) or Cloudflare (1.1.1.1) can help resolve issues in environments where internal DNS is misconfigured.
Warning: Setting
resolver_timeout too high can cause connection delays. A value of 5s is typically sufficient for most setups.
8. Fixing WebSocket Connection Drops
| Issue | Solution | Notes |
|---|---|---|
| WebSocket connection drops after timeout | Adjust proxy_read_timeout and proxy_send_timeout |
Default is 60s. Set to higher value or disable for long-lived connections |
| Connection drops during high traffic | Use keepalive_timeout and proxy_http_version 1.1 |
Ensure proper keep-alive handling for persistent connections |
| Nginx closes WebSocket connection prematurely | Set proxy_set_header Upgrade $http_upgrade; |
Ensure header is forwarded correctly to backend |
Example: Nginx config for WebSocket keep-alive
location /websocket {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 86400;
proxy_send_timeout 86400;
keepalive_timeout 65;
}
Note: Ensure backend server supports WebSocket and handles upgrades correctly.
Warning: Setting timeouts too high may lead to resource exhaustion under heavy load.
9. Debugging Redirect Loops
| Issue | Description | Solution |
|---|---|---|
| Looping redirects | Server continuously redirects between two or more URLs | Check for conflicting rewrite and return directives in configuration |
| Misconfigured SSL redirect | Redirects from HTTP to HTTPS cause infinite loop due to incorrect configuration | Ensure return 301 https://$server_name$request_uri; is correctly applied |
Example: Redirect Loop Configuration
# Incorrect configuration causing loop
location /old-path {
return 301 /new-path;
}
location /new-path {
return 301 /old-path;
}
# Corrected version
location /old-path {
return 301 /new-path;
}
location /new-path {
# Serve content or proxy to backend
}
Note: Use
nginx -t to test configuration before reloading.
Debugging Steps
- Check
error.logfor redirect-related messages - Verify all
rewriteandreturndirectives are not causing cycles - Use
curl -Ito trace redirect chain - Ensure SSL redirect logic does not conflict with other rules
10. Resolving Upstream Connection Refused
| Configuration Directive | Description | Example |
|---|---|---|
| proxy_pass | Specifies the address of the upstream server | proxy_pass http://backend; |
| upstream | Defines a group of servers to be used as upstream | |
| proxy_connect_timeout | Timeout for connecting to the upstream server | proxy_connect_timeout 5s; |
| proxy_send_timeout | Timeout for sending a request to the upstream server | proxy_send_timeout 5s; |
| proxy_read_timeout | Timeout for reading a response from the upstream server | proxy_read_timeout 5s; |
Example: Basic Upstream Configuration
upstream backend {
server 127.0.0.1:8080;
server 127.0.0.1:8081;
}
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
Note: Ensure that the upstream server is running and listening on the specified port.
Warning: If the upstream server is unreachable, Nginx will return a 502 Bad Gateway error.
11. Fixing 400 Bad Request Errors
| Error Code | Description | Common Causes | Solution |
|---|---|---|---|
| 400 Bad Request | The server cannot process the request due to client error | Malformed request line, invalid headers, or oversized request | Check client request format and header size limits |
Example: Logging Request Details
error_log /var/log/nginx/error.log debug;
location / {
access_log /var/log/nginx/access.log;
}
Note: The 400 error often occurs when the request exceeds Nginx's default limits for body size or header length. Adjusting these limits can resolve the issue.
12. Troubleshooting Slow Connections
| Issue | Possible Cause | Solution |
|---|---|---|
| High latency | Network congestion or DNS resolution delays | Use dig to check DNS resolution times. Optimize network routing if needed. |
| Slow response times | Server overload or inefficient configuration | Check nginx -T for config issues. Use limit_req or limit_conn to manage load. |
| Large file transfers | Inefficient buffering or lack of sendfile |
Enable sendfile on; and tune client_body_buffer_size. |
Example: Enabling sendfile for faster file delivery
server {
listen 80;
root /var/www/html;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
location /static/ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
Note: Use
ab or curl -w to benchmark response times and isolate bottlenecks.