When Nginx receives a request for a domain that doesn't match any configured server_name
, it automatically routes the request to the first server block in its configuration. This can lead to unexpected behavior where one of your sites becomes the "catch-all" for invalid domains.
To check which server block is currently acting as default:
nginx -T | grep -A 5 "server {"
This displays all server blocks with their configurations. The first one listed in your nginx.conf or included files becomes the default.
The proper way to handle unmatched domains is to explicitly define a default server block:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
return 444; # Close connection without response
# Or redirect to a specific domain:
# return 301 https://yourmaindomain.com;
}
For production systems, consider these approaches:
# Option 1: Silent drop
server {
listen 80 default_server;
server_name _;
return 444;
}
# Option 2: Maintenance page
server {
listen 80 default_server;
server_name _;
root /var/www/default;
index index.html;
}
# Option 3: Wildcard SSL certificate handling
server {
listen 443 ssl default_server;
server_name _;
ssl_certificate /path/to/wildcard.crt;
ssl_certificate_key /path/to/wildcard.key;
return 403;
}
Use these commands to test and reload your configuration:
nginx -t # Test configuration
systemctl reload nginx # Reload without downtime
- The
default_server
parameter must be specified on thelisten
directive - Multiple IP addresses need separate default declarations
- IPv6 requires its own default server block
- SSL/TLS configurations need separate default blocks
Remember that the default server applies per port and IP address combination. For complex setups, you may need multiple default declarations.
When Nginx receives a request for a domain that doesn't match any configured server_name
directives, it will automatically route that request to:
- The first defined server block in the configuration if no
default_server
is specified - The server block explicitly marked with
default_server
parameter
To check which server block is currently acting as your default:
grep -r "listen.*default_server" /etc/nginx/
Or for a more comprehensive search:
nginx -T | grep -A10 -B5 "default_server"
Here's the recommended way to configure your default server block:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _; # The underscore is a wildcard for unmatched domains
# Recommended: Return 444 (Nginx-specific non-standard code that closes connection)
return 444;
# Alternative: Redirect to your main domain
# return 301 https://yourprimarydomain.com$request_uri;
# Or show a custom error page
# root /var/www/default;
# index index.html;
# try_files $uri /index.html =404;
}
Here's how this works in a real-world setup with multiple domains:
# Primary website
server {
listen 80;
server_name example.com www.example.com;
# ... normal configuration ...
}
# Secondary website
server {
listen 80;
server_name blog.example.com;
# ... normal configuration ...
}
# Default catch-all
server {
listen 80 default_server;
server_name _;
return 444;
}
- The
default_server
parameter must be included in thelisten
directive - Using
server_name _;
is the conventional way to indicate a default server - Always test your configuration with
nginx -t
before reloading - Remember to reload Nginx after changes:
systemctl reload nginx
If your default server isn't working as expected:
# Check which server block is handling requests
nginx -T | grep -A5 -B5 "listen.*80"
# Verify there aren't multiple default_server declarations
nginx -T | grep "default_server" | wc -l
Common mistakes include having multiple default_server
declarations or placing the default server block after other server blocks without proper configuration.