When setting up multiple subdomains in Nginx, you might encounter server name conflicts where requests to one subdomain incorrectly serve content from another. This typically happens when Nginx can't properly distinguish between server blocks.
The key symptom is the warning message during Nginx restart:
nginx: [warn] conflicting server name "" on 0.0.0.0:443, ignored
This indicates Nginx found duplicate or ambiguous server_name definitions for the same IP/port combination.
In your configuration, while you've properly defined server_name
for both HTTP (port 80) blocks, there's a critical omission in your HTTPS (port 443) blocks - they're missing the server_name
directive entirely. Nginx needs this to properly route requests.
Here are the corrected configuration files with explanations:
foo.domain.com
upstream php-handler {
server unix:/var/run/php5-fpm.sock;
}
server {
listen 80;
server_name foo.domain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name foo.domain.com; # THIS WAS MISSING
ssl_certificate [path_foo]/cacert.pem;
ssl_certificate_key [path_foo]/privkey.pem;
root [path]/foo;
# Additional SSL configuration would go here
# ...
}
bar.domain.com
server {
listen 80;
server_name bar.domain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name bar.domain.com; # THIS WAS MISSING
ssl_certificate [path_bar]/cacert.pem;
ssl_certificate_key [path_bar]/privkey.pem;
root [path]/bar;
# Additional SSL configuration would go here
# ...
}
- Always include
server_name
in both HTTP and HTTPS server blocks - The modern Nginx syntax uses
listen 443 ssl
instead of separatessl on
- Consider adding a default server block to catch undefined hostnames
After making changes:
sudo nginx -t # Test configuration
sudo service nginx reload # Apply changes
Verify with:
curl -I http://foo.domain.com
curl -I https://foo.domain.com
curl -I http://bar.domain.com
curl -I https://bar.domain.com
To prevent any future conflicts, add this catch-all block:
server {
listen 80 default_server;
listen 443 ssl default_server;
ssl_certificate /path/to/default/cert.pem;
ssl_certificate_key /path/to/default/key.pem;
return 444; # Close connection without response
}
The warning message you're seeing (conflicting server name "" on 0.0.0.0:443
) typically occurs when Nginx can't properly distinguish between virtual hosts, especially in SSL configurations. The symptom where both subdomains serve the same content indicates Nginx is defaulting to one of your server blocks.
The main issues in your configuration are:
1. Missing server_name in your SSL server blocks
2. Potential certificate mismatch
3. Lack of default_server designation
Here's the corrected configuration for both subdomains:
foo.domain.com
upstream php-handler {
server unix:/var/run/php5-fpm.sock;
}
server {
listen 80;
server_name foo.domain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name foo.domain.com;
ssl_certificate [path_foo]/cacert.pem;
ssl_certificate_key [path_foo]/privkey.pem;
root [path]/foo;
index index.php index.html index.htm;
# Additional PHP-FPM configuration
location ~ \.php$ {
fastcgi_pass php-handler;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
bar.domain.com
server {
listen 80;
server_name bar.domain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name bar.domain.com;
ssl_certificate [path_bar]/cacert.pem;
ssl_certificate_key [path_bar]/privkey.pem;
root [path]/bar;
index index.php index.html index.htm;
# Additional configuration if needed
}
The critical fixes include:
- Added
server_name
to SSL server blocks - Modernized SSL directive syntax (
listen 443 ssl
instead of separatessl on
) - Ensured each subdomain has its own complete configuration
After making these changes:
sudo nginx -t # Test configuration
sudo systemctl restart nginx
Verify using:
curl -I http://foo.domain.com
curl -I https://foo.domain.com
curl -I http://bar.domain.com
curl -I https://bar.domain.com
For more complex setups, consider:
# Wildcard SSL certificate option
server_name *.domain.com;
# Default server catch-all
server {
listen 443 ssl default_server;
server_name _;
return 444; # Close connection
}