NGINX Error Guide: '[emerg] directive is not allowed here' and duplicate location
Fix NGINX [emerg] directive is not allowed here and duplicate location errors: diagnose wrong-context directives, missing braces, stray http blocks, and clashing locations.
- #nginx
- #troubleshooting
- #errors
- #config
Overview
[emerg] "<directive>" directive is not allowed here and [emerg] duplicate location "<path>" are configuration-parse errors. NGINX validates structure before serving anything: every directive is only legal in certain contexts (main, http, server, location, upstream, …), and you cannot define the same location path twice in one server. When a directive sits in the wrong block, or a location clashes, NGINX refuses to load the config — a reload keeps the old config running, a cold start fails entirely.
Typical lines from nginx -t:
nginx: [emerg] "server" directive is not allowed here in /etc/nginx/conf.d/app.conf:42
nginx: [emerg] "location" directive is not allowed here in /etc/nginx/conf.d/app.conf:8
nginx: [emerg] duplicate location "/api/" in /etc/nginx/conf.d/app.conf:30
The message always cites the exact file and line. These are deterministic and entirely fixable from the config — no runtime state involved.
Symptoms
nginx -tfails with[emerg] ... directive is not allowed hereorduplicate location.systemctl reload nginxreports failure; the running config is unchanged.- A cold
systemctl start nginxfails and the service stays dead. - The message points at a specific file and line number.
sudo nginx -t
nginx: [emerg] "location" directive is not allowed here in /etc/nginx/conf.d/app.conf:8
nginx: configuration file /etc/nginx/nginx.conf test failed
sudo systemctl reload nginx
nginx.service: Control process exited, code=exited, status=1/FAILURE
Common Root Causes
1. A directive placed in the wrong context
location, server, proxy_pass, index, etc. each belong to specific blocks. A location written directly under http {} (not inside a server {}), for example, is illegal.
sudo nginx -t
sed -n '1,12p' /etc/nginx/conf.d/app.conf
http {
location / { # <-- location is not allowed directly in http
proxy_pass http://127.0.0.1:8000;
}
}
nginx: [emerg] "location" directive is not allowed here in /etc/nginx/conf.d/app.conf:8
location must live inside a server (or another location). Wrap it in a server {} block.
2. A stray or duplicated http block
Files in conf.d/ are already included inside the main http {}. Adding another http {} inside them nests http in http, which is illegal.
grep -RnE '^\s*http\s*\{' /etc/nginx/nginx.conf /etc/nginx/conf.d/
/etc/nginx/nginx.conf:17:http {
/etc/nginx/conf.d/app.conf:1:http { # extra, nested inside the main http
nginx: [emerg] "http" directive is not allowed here in /etc/nginx/conf.d/app.conf:1
conf.d/*.conf should contain server {} blocks only — remove the redundant http {} wrapper.
3. A missing or unbalanced brace
An unclosed { makes NGINX think a later directive is inside a block that does not accept it, producing a misleading “not allowed here” pointing past the real mistake.
grep -cE '\{' /etc/nginx/conf.d/app.conf
grep -cE '\}' /etc/nginx/conf.d/app.conf
6
5 # one fewer closing brace than opening
nginx: [emerg] "server" directive is not allowed here in /etc/nginx/conf.d/app.conf:42
Brace counts differ; an earlier block was never closed. Fix the missing } (often just above the cited line).
4. Duplicate exact-match location in one server
Two location /api/ {} blocks (same prefix, same server) cannot coexist.
grep -nE 'location\s' /etc/nginx/conf.d/app.conf
12: location /api/ {
30: location /api/ { # exact same prefix in the same server
nginx: [emerg] duplicate location "/api/" in /etc/nginx/conf.d/app.conf:30
Merge the two blocks, or differentiate them (different prefix, or regex vs prefix with ~/=).
5. A server-only directive used in location (or vice versa)
Directives like server_name or listen are not valid inside location; some location-level directives are not valid at server level.
sed -n '20,28p' /etc/nginx/conf.d/app.conf
location /admin/ {
server_name admin.example.com; # server_name is not allowed in location
}
nginx: [emerg] "server_name" directive is not allowed here in /etc/nginx/conf.d/app.conf:22
server_name belongs in the server block. Move it up one level.
6. An included snippet broken or in the wrong context
An included file contains directives valid only in a different context than where it is included, so the error points into the snippet.
grep -RnE 'include' /etc/nginx/conf.d/app.conf
sudo nginx -t
include snippets/proxy.conf;
nginx: [emerg] "location" directive is not allowed here in /etc/nginx/snippets/proxy.conf:3
The snippet defines a location but is included at http level. Include it where its directives are legal (inside a server or location).
Diagnostic Workflow
Step 1: Run nginx -t and read the file:line
sudo nginx -t
The [emerg] line names the file and line number of the offending directive (or the duplicate location). That is your starting point — though for brace errors the real cause is often earlier.
Step 2: Look at the cited line in context
sed -n '1,50p' /etc/nginx/conf.d/app.conf | cat -n
Identify which block the directive is actually inside. Ask: is this directive legal in this context? Cross-check against the NGINX directive index if unsure.
Step 3: Check brace balance
grep -cE '\{' /etc/nginx/conf.d/app.conf
grep -cE '\}' /etc/nginx/conf.d/app.conf
Unequal counts mean a missing/extra brace upstream is shifting everything into the wrong context. Fix the imbalance first — it often resolves a misleading “not allowed here”.
Step 4: For duplicate location, list every location in the server
grep -nE 'location\s' /etc/nginx/conf.d/app.conf
Find the two identical prefixes in the same server. Merge their contents into one block, or make one a regex/exact match so they no longer collide.
Step 5: Validate again, then reload
sudo nginx -t
sudo systemctl reload nginx
nginx -t must print test is successful before you reload. Never reload on a failed test — at best nothing changes, at worst a cold restart fails.
Example Root Cause Analysis
A teammate adds a new proxy block and the deploy’s systemctl reload nginx fails. The running site is unaffected (old config still loaded), but the new route never appears.
Running the test:
sudo nginx -t
nginx: [emerg] "location" directive is not allowed here in /etc/nginx/conf.d/api.conf:3
nginx: configuration file /etc/nginx/nginx.conf test failed
Looking at the file:
sed -n '1,10p' /etc/nginx/conf.d/api.conf | cat -n
1 location /api/ {
2 proxy_pass http://127.0.0.1:9000;
3 }
The file defines a bare location with no enclosing server {}. Since conf.d/*.conf is included at http level, a top-level location is illegal — it must be inside a server.
Fix: wrap the location in a server block, validate, and reload:
server {
listen 80;
server_name api.example.com;
location /api/ {
proxy_pass http://127.0.0.1:9000;
}
}
sudo nginx -t
sudo systemctl reload nginx
nginx: configuration file /etc/nginx/nginx.conf test is successful
The new route loads.
Prevention Best Practices
- Always run
nginx -tbefore every reload and gate deploys on it; these are parse errors caught instantly, so no broken config should ever ship. - Keep
conf.d/*.conffiles toserver {}blocks (andupstream {}) only — never wrap them in anotherhttp {}, which is already provided bynginx.conf. - Use an editor with brace matching / NGINX syntax highlighting; the majority of “not allowed here” errors are a missing
}shifting context. - Name and scope
includesnippets by the context they belong to (e.g.snippets/proxy_location.confincluded only inside alocation) so they cannot be pasted into the wrong block. - Review
locationprefixes when adding routes to avoid duplicates; prefer exact (=) or regex (~) matches where intent is specific. - For a quick read of a failed
nginx -t, the free incident assistant can map the[emerg]line to the wrong-context or duplicate cause. More fixes live in the NGINX guides.
Quick Command Reference
# Validate and read the offending file:line
sudo nginx -t
# Inspect the cited area with line numbers
sed -n '1,50p' /etc/nginx/conf.d/app.conf | cat -n
# Check brace balance
grep -cE '\{' /etc/nginx/conf.d/app.conf
grep -cE '\}' /etc/nginx/conf.d/app.conf
# Find stray http blocks and all locations
grep -RnE '^\s*http\s*\{' /etc/nginx/nginx.conf /etc/nginx/conf.d/
grep -nE 'location\s' /etc/nginx/conf.d/app.conf
# Re-validate and reload
sudo nginx -t && sudo systemctl reload nginx
Conclusion
[emerg] ... is not allowed here and duplicate location are structural config errors NGINX rejects before serving. The usual root causes:
- A directive placed in the wrong context (e.g.
locationdirectly inhttp). - A stray/nested
http {}inside aconf.dfile. - A missing or unbalanced brace shifting later directives into the wrong block.
- Two identical
locationprefixes in the sameserver. - A
server-only directive used inlocation(or vice versa). - An
included snippet pulled into the wrong context.
The error always cites a file and line — check the directive’s context there, fix braces first, then nginx -t until it reports success before reloading.
Download the Free 500-Prompt DevOps AI Toolkit
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.