How to Fix “Nginx duplicate default server error” When Configuring Multiple Virtual Hosts


5 views

The error occurs when Nginx detects multiple server blocks attempting to act as the default server for the same port (in this case, port 80). In your configuration:

# /etc/nginx/sites-enabled/default
server {
    listen   80; # ipv4
    listen   [::]:80 default ipv6only=on; # ipv6 << Problem line
}

# /etc/nginx/nginx.conf
http {
    server {
        server_name mydomain;
        listen 3000;
        root /projects/myproject/public;
    }
}

The key issue is the default parameter in your IPv6 listen directive. This makes this server block the default catch-all for any requests on port 80 that don't match other server_name directives. When Nginx finds another server block listening on the same port without explicit server_name differentiation, it throws this error.

Here's how to properly structure your configuration:

# Main configuration file (/etc/nginx/nginx.conf)
http {
    # Default server for unmatched requests
    server {
        listen 80 default_server;
        listen [::]:80 default_server;
        server_name _;
        return 444; # Close connection for unmatched requests
    }

    # Your custom domain
    server {
        listen 80;
        listen [::]:80;
        server_name mydomain.com www.mydomain.com;
        root /var/www/mydomain;
        # Additional config...
    }

    # Your custom port application
    server {
        listen 3000;
        server_name mydomain.com;
        root /projects/myproject/public;
        # Additional config...
    }
}
  • Only one default_server declaration per IP:port combination
  • Always include both IPv4 and IPv6 listen directives for consistency
  • Use server_name _; for true default/catch-all servers
  • Consider returning HTTP 444 for default servers to drop invalid requests

After making changes:

sudo nginx -t # Test configuration
sudo systemctl restart nginx # Apply changes

If you need to serve different default content per IP address:

server {
    listen 192.0.2.1:80 default_server;
    # Config for IP 192.0.2.1
}

server {
    listen 192.0.2.2:80 default_server;
    # Config for IP 192.0.2.2
}

When working with Nginx configurations, you might encounter the "duplicate default server" error, especially when setting up multiple server blocks. This occurs when Nginx detects more than one server block attempting to act as the default server for a particular port.

# Error message example
the duplicate default server in /etc/nginx/sites-enabled/default:10
configuration file /etc/nginx/nginx.conf test failed

In your configuration, the issue stems from having two server blocks both trying to handle requests on port 80. The first server block in /etc/nginx/sites-enabled/default has:

listen   80; ## listen for ipv4
listen   [::]:80 default ipv6only=on; ## listen for ipv6

The key problem is the default parameter in the IPv6 listen directive, which marks this server block as the default for port 80.

Here are three ways to resolve this:

Option 1: Remove the default flag

Modify your default configuration to:

listen   80;
listen   [::]:80;

Option 2: Explicit default servers

If you need specific default servers for different ports:

# For port 80
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    # ... rest of configuration
}

# For port 3000
server {
    listen 3000 default_server;
    # ... rest of configuration
}

Option 3: Separate server_name directives

For better organization:

# Default catch-all
server {
    listen 80 default_server;
    server_name _;
    return 444; # Or custom 404 page
}

# Your main domain
server {
    listen 80;
    server_name example.com;
    # ... rest of configuration
}

When working with multiple Nginx server blocks:

  • Only one server block should be marked as default per port
  • Use explicit server_name directives for all non-default servers
  • Consider creating a catch-all default server that returns 444 (connection closed) or a custom 404
  • Keep all server configurations in /etc/nginx/sites-available/ and symlink to sites-enabled/

Always test your Nginx configuration before restarting:

sudo nginx -t

If successful, reload Nginx:

sudo systemctl reload nginx