Nginx Errors: Conflicting server_name, 413, and upstream Errors
Common nginx configuration errors: conflicting server_name on the same port (duplicate default_server or duplicate hostname), 413 Request Entity Too Large from client_max_body_size, 502 Bad Gateway from upstream connection failure, and 499 client closed request from slow backends. nginx -t validates config without restarting.
Conflicting server_name
nginx: [warn] conflicting server name "_" on 0.0.0.0:80, ignored
Two server blocks have the same server_name and listen combination. Common cause: including a default sites-enabled/default alongside a custom config that also uses server_name _;:
# File 1: /etc/nginx/sites-enabled/default
server {
listen 80 default_server;
server_name _;
# ...
}
# File 2: /etc/nginx/sites-enabled/myapp
server {
listen 80 default_server; # ← conflict: two default_server on same port
server_name _;
# ...
}
Fix: only one default_server per IP:port. Remove or modify the duplicate:
# Disable the default site
rm /etc/nginx/sites-enabled/default
nginx -t && nginx -s reload
413 Request Entity Too Large
413 Request Entity Too Large
The request body exceeds client_max_body_size (default: 1MB):
http {
client_max_body_size 50M; # applies to all server blocks
}
server {
listen 80;
server_name upload.example.com;
client_max_body_size 100M; # override for this server block
location /api/upload {
client_max_body_size 500M; # override for this location
}
}
nginx reads the body in chunks and rejects incrementally — if the body exceeds the limit mid-transfer, nginx returns 413 immediately without waiting for the full upload. The limit applies to the total body size including multipart boundaries.
PHP has its own upload limits separate from nginx — both must be configured for large file uploads
GotchaNginx / PHPWhen nginx proxies to PHP-FPM, three separate limits must be set: nginx's client_max_body_size (controls what nginx accepts), PHP's upload_max_filesize (controls the max size of a single file in a multipart upload), and PHP's post_max_size (controls the total POST body size, must be >= upload_max_filesize). If nginx allows 100MB but PHP's post_max_size is 8MB (default), PHP silently treats the request as having no body — the upload fails without a useful error message.
Prerequisites
- nginx proxy_pass
- PHP-FPM
- multipart/form-data
Key Points
- client_max_body_size in nginx: rejects oversized requests with 413.
- upload_max_filesize in php.ini: max size of one uploaded file.
- post_max_size in php.ini: max total POST body size. Must be >= upload_max_filesize.
- nginx 413 vs PHP silent failure: 413 is clear; PHP silently drops the body if post_max_size is exceeded.
502 Bad Gateway
502 Bad Gateway
nginx cannot connect to the upstream (backend application):
upstream backend {
server app:8080;
}
server {
location / {
proxy_pass http://backend;
proxy_connect_timeout 5s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
}
}
Common causes:
- Backend is down or not started
- Wrong upstream address or port
- Backend is listening on 127.0.0.1 (loopback) but nginx is in a different network namespace (Docker)
proxy_connect_timeoutexceeded (backend too slow to accept connections)
Debug:
# Check if backend is running and listening
ss -tlnp | grep 8080
# Test connection from nginx container (Docker)
docker exec nginx-container curl http://app:8080/health
# Check nginx error logs
tail -f /var/log/nginx/error.log
499 Client Closed Request
499 0.000 [info] client closed request while waiting for response
The client disconnected before the backend responded. Common in slow API calls where the browser or mobile client has a shorter timeout than the backend processing time. Not an nginx error — it's the client leaving.
If you see many 499s, the backend is too slow. Solutions: optimize the endpoint, add a loading state with polling, or return a 202 Accepted with an async job ID.
An nginx server returns 413 for file uploads over 5MB. You set `client_max_body_size 100M` in the server block. Uploads still fail at 5MB. Why?
mediumThere is an http {} block and a server {} block. nginx configuration has inheritance — server block values override http block values.
AThe server block setting doesn't override the http block setting
Incorrect.nginx settings are inherited from outer context to inner context, and inner blocks can override outer blocks. A server block client_max_body_size overrides the http block value for that server.BAnother client_max_body_size directive in the http {} block or the location {} block takes precedence, or the PHP post_max_size is still at 5MB
Correct!Two scenarios: (1) A conflicting client_max_body_size in a more-specific location block (location / { client_max_body_size 5M; }) overrides the server-level setting. Inner blocks take precedence. (2) The nginx setting is correct at 100M, but PHP's post_max_size or upload_max_filesize is still at the old limit (5MB or 8MB default). PHP silently drops oversized POST bodies, and the application responds as if no file was uploaded. Check both nginx config (nginx -T | grep client_max_body_size) and php.ini (php -i | grep upload_max_filesize).Cnginx -s reload is required after every config change
Incorrect.nginx -s reload is required to apply config changes — if you edited the config and didn't reload, the old limit would still apply. But the question implies the change is in place and still failing, suggesting either a more-specific override or a different system's limit.Dclient_max_body_size can only be set in the http {} block, not server {} blocks
Incorrect.client_max_body_size can be set in http {}, server {}, and location {} contexts. More specific context overrides less specific.
Hint:Where else besides the server block could a 5MB limit come from?