Nginx is failing to start because it’s found two identical location blocks in your configuration, and it doesn’t know which one to use.

Here’s what’s actually happening: Nginx parses your configuration files and builds an internal routing table. When it encounters two location blocks that resolve to the exact same URI path, it throws an error because it cannot deterministically select a handler for incoming requests matching that path. It needs a single, unambiguous rule for each request.

Common Causes and Fixes:

  1. Accidental Copy-Paste: You or a colleague likely copied a location block and forgot to change the path or a directive within it, leading to a duplicate.

    • Diagnosis: Run sudo nginx -t. The output will pinpoint the exact file and line number of the duplicate location block.
    • Fix: Manually edit the configuration file. Delete one of the identical location blocks or, more commonly, modify one to handle a slightly different path (e.g., add a trailing slash or a wildcard). For example, if you have:
      location /app/ {
          proxy_pass http://backend_app;
      }
      
      location /app/ { # Duplicate!
          alias /var/www/html/app/;
      }
      
      You would either remove the second block or change it to:
      location /app-static/ {
          alias /var/www/html/app/;
      }
      
      This works because Nginx now has two distinct rules for different incoming URIs.
    • Why it works: Each location block now maps to a unique URI pattern, resolving the ambiguity.
  2. Conflicting include Directives: You might have multiple include statements that pull in configuration files containing the same location block.

    • Diagnosis: The sudo nginx -t output will still show the duplicate location but might not immediately reveal which included file is causing it if it’s buried deep. Use grep -r "location /your/path/" /etc/nginx/conf.d/ (replace /your/path/ with the problematic path and /etc/nginx/conf.d/ with your include directory) to find all occurrences.
    • Fix: Examine the output of grep. Identify the duplicated location block and ensure it’s only included once. This might involve removing one of the include directives or modifying one of the included files to remove the duplicate. For instance, if conf.d/app.conf and conf.d/legacy.conf both contain location /api/, you’d remove the duplicate from one of them.
      # In nginx.conf or a main conf file
      include /etc/nginx/conf.d/*.conf;
      # If app.conf and legacy.conf both have the same location,
      # you must edit one of them to remove the duplicate.
      
    • Why it works: By ensuring the location block is parsed only once, Nginx avoids the ambiguity.
  3. Case Sensitivity Mismatch (Less Common on Linux, but possible): On case-sensitive file systems or with specific Nginx configurations, location /App/ might be treated differently than location /app/. However, Nginx itself typically normalizes URIs to lowercase before matching location blocks unless specific regex is used. The error usually means an exact duplicate.

    • Diagnosis: This is rarely the cause of the exact duplicate error, but if other causes are ruled out, check for subtle case differences in your location directives.
    • Fix: Standardize on lowercase for location paths.
      # Change this:
      location /API/ { ... }
      # To this:
      location /api/ { ... }
      
    • Why it works: Ensures identical URI matching.
  4. Regex vs. Prefix Location Ambiguity: While not strictly a "duplicate" error, Nginx has specific rules for matching location blocks. If you have a prefix match (location /app/) and a regex match (location ~ ^/app/.*) that overlap or are identical in effect, it can sometimes lead to confusing errors or unexpected behavior, though Nginx usually prioritizes regex. The explicit "duplicate" error is usually for identical prefix blocks.

    • Diagnosis: Review your location blocks. Look for combinations of prefix and regex matches that cover the same URI space.
    • Fix: Refine your location blocks to be distinct. If you need a regex for /app/, ensure no other prefix block also matches /app/ exactly.
      # If you have this:
      location /app/ { ... } # Prefix match
      location ~ ^/app/?$ { ... } # Regex match for /app/ or /app
      # Consider consolidating or making them distinct:
      location /app/ {
          # Directives for /app/ and anything under it
      }
      location = /app {
          # Specific directives for exactly /app
      }
      
    • Why it works: Nginx has clear, non-overlapping rules for each URI.
  5. Server Block Duplication: If you have multiple server blocks that are configured to listen on the exact same port and server_name (or default server), and within those blocks, you have duplicate location blocks, Nginx might report the error associated with the first server block it encounters that contains the duplicate.

    • Diagnosis: Run sudo nginx -T (uppercase T to show all loaded configurations, including included files) and carefully examine all server blocks for identical listen and server_name directives. Then, look for the duplicate location within these identical server blocks.
    • Fix: Ensure each server block has a unique combination of listen and server_name. If you have a default server, make sure there’s only one. Then, fix the duplicate location block within the relevant server block.
      # In nginx.conf or a main conf file
      http {
          server {
              listen 80 default_server;
              server_name example.com;
              location / { ... } # Duplicate here
          }
          server {
              listen 80 default_server; # Duplicate listen/default_server!
              server_name example.com;
              location / { ... } # Duplicate here
          }
      }
      
      Correct by making server blocks unique:
      http {
          server {
              listen 80;
              server_name example.com;
              location / { ... }
          }
          server {
              listen 80;
              server_name www.example.com; # Different server_name
              location / { ... }
          }
          server {
              listen 80 default_server; # Only one default_server
              # No server_name or a catch-all
              location / { ... }
          }
      }
      
    • Why it works: Each server block is uniquely identified, and the location ambiguity is resolved within its specific server context.
  6. Nginx Configuration Generation Tools: If you’re using tools like Puppet, Chef, Ansible, or custom scripts to generate your Nginx configuration, a bug in the tool or its playbook can lead to duplicate location blocks being written.

    • Diagnosis: Inspect the generated Nginx configuration files (/etc/nginx/nginx.conf and files in conf.d/ or sites-enabled/). Look for the duplicate location block.
    • Fix: Debug the configuration generation tool or script. Correct the logic that is producing the duplicate. For example, if your template has a loop that accidentally adds the same location block twice, fix the loop.
    • Why it works: The generation process now produces a clean, non-duplicated configuration.

After fixing the duplicate location block and running sudo nginx -t to confirm the syntax is now correct, the next error you’ll likely encounter is a "port already in use" error if you were also trying to start Nginx on a port that another process (or another Nginx instance) is already occupying.

Want structured learning?

Take the full Nginx course →