Nginx is failing to start because it’s finding multiple server blocks that claim to handle the same hostname and port, and it doesn’t know which one to pick.

Common Causes and Fixes

  1. Duplicate server_name directives within a single server block:

    • Diagnosis: Inspect the Nginx configuration file(s) where the warning appears. Look for a server block that has the same server_name listed multiple times.
      server {
          listen 80;
          server_name example.com www.example.com example.com; # Duplicate
          # ...
      }
      
    • Fix: Remove the duplicate server_name entries.
      server {
          listen 80;
          server_name example.com www.example.com; # Fixed
          # ...
      }
      
    • Why it works: Nginx parses directives sequentially. While it can technically handle multiple server_name entries, listing the same one twice is redundant and can confuse its internal parsing, triggering the warning.
  2. Identical server_name directives in different server blocks listening on the same port:

    • Diagnosis: This is the most common scenario. Run nginx -t to see the specific file and line numbers causing the conflict. Then, manually inspect those server blocks.
      # /etc/nginx/sites-available/site1.conf
      server {
          listen 80;
          server_name example.com;
          # ...
      }
      
      # /etc/nginx/sites-available/site2.conf
      server {
          listen 80;
          server_name example.com; # Conflict
          # ...
      }
      
    • Fix: Ensure each server_name is unique for a given listen directive. You can either:
      • Make server_name unique: Change one of the server_name directives.
        # /etc/nginx/sites-available/site2.conf
        server {
            listen 80;
            server_name staging.example.com; # Changed
            # ...
        }
        
      • Use a wildcard or regex: If you intend for both to match, use Nginx’s wildcard or regex capabilities.
        # /etc/nginx/sites-available/site1.conf
        server {
            listen 80;
            server_name *.example.com; # Wildcard
            # ...
        }
        
        # /etc/nginx/sites-available/site2.conf
        server {
            listen 80;
            server_name example.com; # Specific
            # ...
        }
        
      • Use a default server: Designate one of the conflicting blocks as the default for that IP/port combination.
        # /etc/nginx/sites-available/site1.conf
        server {
            listen 80 default_server; # Default
            server_name example.com;
            # ...
        }
        
        # /etc/nginx/sites-available/site2.conf
        server {
            listen 80;
            server_name www.example.com; # Different, or a fallback
            # ...
        }
        
    • Why it works: Nginx needs a deterministic way to choose which server block handles an incoming request. If multiple blocks claim the same hostname on the same port, it’s ambiguous. Explicitly defining unique names, using Nginx’s matching patterns, or designating a default_server provides Nginx with the necessary logic.
  3. Conflicting server_name with different listen directives but the same IP:

    • Diagnosis: Sometimes the conflict isn’t on the exact same listen directive but on the same IP address, especially when using IPv6.
      server {
          listen [::]:80; # IPv6
          server_name example.com;
          # ...
      }
      
      server {
          listen 80; # IPv4
          server_name example.com; # Conflict on the same hostname
          # ...
      }
      
    • Fix: Treat IPv4 and IPv6 listen directives as distinct unless you explicitly want them to share server_name configuration. Ensure server_name is unique across both.
      server {
          listen [::]:80;
          server_name example.com; # Unique for IPv6
          # ...
      }
      
      server {
          listen 80;
          server_name www.example.com; # Unique for IPv4
          # ...
      }
      
    • Why it works: Nginx considers listen 80 (IPv4) and listen [::]:80 (IPv6) as separate listening sockets. A server_name that matches a request arriving on one socket must be unique to that socket’s configuration.
  4. Using include directives that unintentionally create duplicates:

    • Diagnosis: If your configuration is spread across multiple files using include, a server_name defined in one included file might be duplicated by another server block in a different included file or the main configuration.
      # /etc/nginx/nginx.conf
      http {
          include /etc/nginx/conf.d/*.conf;
          include /etc/nginx/sites-enabled/*;
      }
      
      # /etc/nginx/conf.d/default.conf
      server {
          listen 80;
          server_name example.com;
          # ...
      }
      
      # /etc/nginx/sites-enabled/my-site.conf
      server {
          listen 80;
          server_name example.com; # Duplicate from default.conf
          # ...
      }
      
    • Fix: Review the include paths and the server blocks within those files. Consolidate common server_name directives or rename them. Use grep to find all occurrences of a specific server_name across your Nginx configuration directory.
      grep -r "server_name example.com;" /etc/nginx/
      
    • Why it works: The include directive essentially pastes the content of one file into another during Nginx’s configuration parsing. If that content, when combined, results in duplicate server_name declarations for the same port, the conflict arises.
  5. Wildcard server_name conflicts:

    • Diagnosis: Wildcards (*.example.com) and exact names (example.com) can conflict if not managed carefully.
      server {
          listen 80;
          server_name *.example.com; # Matches anything.example.com
          # ...
      }
      
      server {
          listen 80;
          server_name api.example.com; # This is also matched by the above
          # ...
      }
      
    • Fix: Nginx prioritizes more specific matches. An exact match (example.com) is more specific than a wildcard (*.example.com), and a wildcard is more specific than a catch-all (_ or empty server_name). Ensure your most specific configurations are listed first or have unique server_name directives.
      server {
          listen 80;
          server_name example.com; # Most specific first
          # ...
      }
      
      server {
          listen 80;
          server_name *.example.com; # Wildcard
          # ...
      }
      
    • Why it works: Nginx resolves hostname matches in a specific order: exact matches first, then wildcards (longest matching prefix, then longest matching suffix), then regular expressions, and finally the default server. Explicitly ordering or ensuring uniqueness prevents ambiguity.
  6. Using _ (underscore) as a server_name to catch all other requests:

    • Diagnosis: The _ is a valid, albeit unusual, server_name that acts as a catch-all. If you have multiple server blocks that could catch a request (e.g., a default server and a _ server), Nginx will warn.
      server {
          listen 80 default_server;
          server_name _; # Catch-all
          # ...
      }
      
      server {
          listen 80;
          server_name example.com;
          # ...
      }
      
    • Fix: Ensure you only have one server block designated as the default_server for a given listen directive, and that its server_name (whether _ or an actual hostname) doesn’t conflict with other explicit server_name entries. Often, the default_server is sufficient without needing an explicit _.
    • Why it works: The default_server directive is Nginx’s primary mechanism for handling requests that don’t match any other defined server_name. Using _ as a server_name in addition to default_server can sometimes lead to Nginx questioning the intent, especially if other blocks are also present.

After fixing these, the next error you’ll likely encounter is a "permission denied" error if Nginx isn’t running as root and trying to bind to privileged ports like 80 or 443.

Want structured learning?

Take the full Nginx course →