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
-
Duplicate
server_namedirectives within a singleserverblock:- Diagnosis: Inspect the Nginx configuration file(s) where the warning appears. Look for a
serverblock that has the sameserver_namelisted multiple times.server { listen 80; server_name example.com www.example.com example.com; # Duplicate # ... } - Fix: Remove the duplicate
server_nameentries.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_nameentries, listing the same one twice is redundant and can confuse its internal parsing, triggering the warning.
- Diagnosis: Inspect the Nginx configuration file(s) where the warning appears. Look for a
-
Identical
server_namedirectives in differentserverblocks listening on the same port:- Diagnosis: This is the most common scenario. Run
nginx -tto see the specific file and line numbers causing the conflict. Then, manually inspect thoseserverblocks.# /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_nameis unique for a givenlistendirective. You can either:- Make
server_nameunique: Change one of theserver_namedirectives.# /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 # ... }
- Make
- Why it works: Nginx needs a deterministic way to choose which
serverblock 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 adefault_serverprovides Nginx with the necessary logic.
- Diagnosis: This is the most common scenario. Run
-
Conflicting
server_namewith differentlistendirectives but the same IP:- Diagnosis: Sometimes the conflict isn’t on the exact same
listendirective 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
listendirectives as distinct unless you explicitly want them to shareserver_nameconfiguration. Ensureserver_nameis 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) andlisten [::]:80(IPv6) as separate listening sockets. Aserver_namethat matches a request arriving on one socket must be unique to that socket’s configuration.
- Diagnosis: Sometimes the conflict isn’t on the exact same
-
Using
includedirectives that unintentionally create duplicates:- Diagnosis: If your configuration is spread across multiple files using
include, aserver_namedefined in one included file might be duplicated by anotherserverblock 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
includepaths and theserverblocks within those files. Consolidate commonserver_namedirectives or rename them. Usegrepto find all occurrences of a specificserver_nameacross your Nginx configuration directory.grep -r "server_name example.com;" /etc/nginx/ - Why it works: The
includedirective essentially pastes the content of one file into another during Nginx’s configuration parsing. If that content, when combined, results in duplicateserver_namedeclarations for the same port, the conflict arises.
- Diagnosis: If your configuration is spread across multiple files using
-
Wildcard
server_nameconflicts:- 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 emptyserver_name). Ensure your most specific configurations are listed first or have uniqueserver_namedirectives.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.
- Diagnosis: Wildcards (
-
Using
_(underscore) as aserver_nameto catch all other requests:- Diagnosis: The
_is a valid, albeit unusual,server_namethat acts as a catch-all. If you have multipleserverblocks 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
serverblock designated as thedefault_serverfor a givenlistendirective, and that itsserver_name(whether_or an actual hostname) doesn’t conflict with other explicitserver_nameentries. Often, thedefault_serveris sufficient without needing an explicit_. - Why it works: The
default_serverdirective is Nginx’s primary mechanism for handling requests that don’t match any other definedserver_name. Using_as aserver_namein addition todefault_servercan sometimes lead to Nginx questioning the intent, especially if other blocks are also present.
- Diagnosis: The
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.