NGINX Error Guide: 'duplicate location' — fix conflicting location blocks
Fix NGINX 'duplicate location' errors that fail nginx -t: find repeated location blocks, included-file collisions, and prefix vs regex confusion, then consolidate and reload safely.
- #nginx
- #web-server
- #troubleshooting
- #errors
Stuck on this NGINX error? Get the free incident triage checklist
A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.
Overview
NGINX refuses to start or reload when the same location is declared twice inside one server block. nginx -t fails immediately with the exact file and line of the collision, and the reload is aborted — the running config is left untouched, but no new config loads until you fix it.
nginx: [emerg] duplicate location "/" in /etc/nginx/conf.d/app.conf:42
nginx: configuration file /etc/nginx/nginx.conf test failed
The message names the offending location string and the file:line of the second occurrence. Note this is only about identical prefix locations within the same server; a prefix location / and a regex location ~ \.php$ are not duplicates.
Symptoms
nginx -tfails with[emerg] duplicate location "...".systemctl reload nginxfails and the new config does not take effect.- The error appeared after adding a snippet, copy-pasting a block, or including a shared file into multiple servers.
- Two teams edited the same vhost and both added the same path handler.
sudo nginx -t
nginx: [emerg] duplicate location "/api/" in /etc/nginx/conf.d/app.conf:57
nginx: configuration file /etc/nginx/nginx.conf test failed
Common Root Causes
1. Literally the same location declared twice
The most common case — a block was copy-pasted or a handler added without noticing an existing one for the same path.
location /api/ {
proxy_pass http://backend;
}
# ... 20 lines later ...
location /api/ { # duplicate in the same server{}
proxy_pass http://backend_v2;
}
2. An include pulls in a block that also exists inline
A shared snippet under include defines a location that the vhost also declares directly, so the merged config has two.
server {
include snippets/well-known.conf; # defines location /.well-known/
location /.well-known/ { ... } # also defined here -> duplicate
}
3. The same snippet included twice
A snippet is included both directly and transitively (via another include), landing the same location in one server twice.
include snippets/security.conf; # includes locations.conf
include snippets/locations.conf; # included again -> duplicates
4. Exact-match and prefix confusion
location = /health (exact) and location /health (prefix) are different and coexist fine — but two location = /health or two plain location /health collide. Mixing up which you wrote leads to an accidental exact duplicate.
Diagnostic Workflow
Step 1: Let nginx -t point at the collision
sudo nginx -t
The [emerg] duplicate location "X" in file:line tells you the location string and the second occurrence’s file and line. Start there.
Step 2: Find every declaration of that location string
Search across the full config tree, not just the named file — the first copy may live in an included snippet:
grep -RnE 'location\s+(=\s+)?/api/' /etc/nginx/nginx.conf /etc/nginx/conf.d/ /etc/nginx/sites-enabled/ /etc/nginx/snippets/
/etc/nginx/conf.d/app.conf:31: location /api/ {
/etc/nginx/conf.d/app.conf:57: location /api/ {
Two hits inside the same server {} confirm the duplicate.
Step 3: Confirm they are in the same server block
Only duplicates within one server {} are an error; the same path in two different servers is fine. Dump the parsed config to see structure:
sudo nginx -T | grep -nE 'server_name|location\s+/api/'
# Correct: consolidate into one location; use nested logic instead of two blocks
location /api/ {
# route by version with a map or a nested prefix, not a second location /api/
proxy_pass http://backend;
}
# Fine and NOT a duplicate: exact vs prefix coexist
location = /health { return 200 "ok\n"; }
location /health/ { proxy_pass http://health_backend; }
Step 4: Remove/merge, then validate and reload
sudo nginx -t && sudo systemctl reload nginx
Example Root Cause Analysis
After adding a shared security snippet to a vhost, nginx -t fails on reload:
nginx: [emerg] duplicate location "/.well-known/acme-challenge/" in /etc/nginx/conf.d/site.conf:48
Searching every config file for that location string:
grep -RnE 'location\s+/.well-known/acme-challenge/' /etc/nginx/conf.d/ /etc/nginx/snippets/
/etc/nginx/snippets/acme.conf:3: location /.well-known/acme-challenge/ {
/etc/nginx/conf.d/site.conf:48: location /.well-known/acme-challenge/ {
The vhost both includes snippets/acme.conf (which defines the ACME challenge location) and declares the same location inline — a leftover from before the snippet existed. Removing the inline copy resolves it:
server {
include snippets/acme.conf; # keep the shared definition
# deleted the duplicate inline location /.well-known/acme-challenge/ { ... }
}
sudo nginx -t && sudo systemctl reload nginx # test passes, reload succeeds
Prevention Best Practices
- Use
nginx -T(capital T) to review the fully assembled config; it reveals duplicate locations introduced by includes that a single-file grep would miss. - Keep each path’s handling in exactly one place — route variations (API versions, A/B) with a
mapor nested logic, not two identically-namedlocationblocks. - Include shared snippets once per server; audit for a snippet pulled in both directly and transitively.
- Remember exact (
location = /x) and prefix (location /x) are distinct and legal together — do not “fix” a non-duplicate by deleting the wrong one. - Validate every change with
nginx -tbefore reload; the emerg names the exact file:line, so fixes are fast.
Quick Command Reference
# Point at the collision
sudo nginx -t
# Find every declaration of the location string (whole tree)
grep -RnE 'location\s+(=\s+)?/api/' /etc/nginx/nginx.conf /etc/nginx/conf.d/ /etc/nginx/sites-enabled/ /etc/nginx/snippets/
# See the fully assembled config and where the location appears
sudo nginx -T | grep -nE 'server_name|location\s+/api/'
# Validate and reload after consolidating
sudo nginx -t && sudo systemctl reload nginx
Conclusion
duplicate location is a hard [emerg] config error: NGINX will not load a server block that declares the same location twice. The usual root causes:
- The same
locationcopy-pasted or added twice in one server. - An
includethat defines a location the vhost also declares inline. - The same snippet included twice, directly and transitively.
- Confusing exact-match (
=) with prefix locations.
Trust the file:line in the emerg, grep the whole config tree (including snippets) for the location string, confirm both live in the same server block, then consolidate into a single handler and nginx -t before reloading. nginx -T is your fastest way to see duplicates that includes introduced.
Fixed it? Get 500 NGINX & DevOps AI prompts — free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.
Did this fix your issue?
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.