Understanding Nginx Location Matching: Rules, Prefixes, and Practical Examples
This article explains Nginx's location matching order, distinguishes literal and regex locations, clarifies the effects of prefixes like =, ^~, and @, provides detailed configuration examples, test results, and installation tips for the rewrite module.
Official Documentation Explanation
Reference: http://wiki.nginx.org/NginxHttpCoreModule#location
location syntax: location [=|~|~*|^~|@] /uri/ { … }
default: no
context: server
This directive allows different configurations depending on the URI.
Literal vs. Regular‑Expression Locations
Literal locations use plain strings, while regular‑expression locations use patterns prefixed with
~(case‑sensitive) or
~*(case‑insensitive). The prefixes
=,
^~, and
@have special meanings.
Matching Order
When processing a request, Nginx checks locations in the following order:
Exact match directives with the "=" prefix. If found, search stops.
All remaining literal string locations. If a match uses the "^~" prefix, search stops.
Regular‑expression locations, in the order they appear in the configuration file. The first matching regex stops further searching.
If a regex matched, its result is used; otherwise the result from step 2 is used.
Literal strings are matched first; the most specific (longest) prefix wins. If the best literal match is an exact match (or uses
=or
^~), Nginx does not evaluate regular‑expression locations.
Prefix Effects
=– exact match only; stops further searching.
^~– non‑regex prefix; stops regex search even if the match is a longest‑prefix match.
@– defines a named location used for internal redirects (e.g., with
error_page).
Practical Examples
Example 1 – Literal then Regex
<code>server {
listen 9090;
server_name localhost;
location / {
root html;
index index.html index.htm;
deny all;
}
location ~ \.html$ {
allow all;
}
}
</code>Requests:
curl http://localhost:9090/→ 403 Forbidden (matched exact literal
/with
deny all).
curl http://localhost:9090/index.html→ Welcome page (literal
/matches as longest prefix, then regex
~ \.html$overrides and allows access).
curl http://localhost:9090/index_notfound.html→ 404 Not Found (allowed by regex but file missing).
curl http://localhost:9090/index.txt→ 403 Forbidden (no regex match, longest‑prefix literal applies).
Example 2 – Exact Literal Match Stops Regex
<code>server {
listen 9090;
server_name localhost;
location /exact/match.html { allow all; }
location / { root html; index index.html index.htm; deny all; }
location ~ \.html$ { allow all; }
}
</code>Request
curl http://localhost:9090/exact/match.htmlreturns 404 because the exact literal location is matched first and prevents the regex from being evaluated.
Example 3 – Using ^~ Prefix
<code>server {
listen 9090;
server_name localhost;
location /exact/match.html { allow all; }
location ^~ / { root html; index index.html index.htm; deny all; }
location ~ \.html$ { allow all; }
}
</code>Now any request starting with
/(including
/index.html) is stopped after the
^~ /block, so the regex no longer overrides it.
Example 4 – Using = Prefix
<code>server {
listen 9090;
server_name localhost;
location /exact/match.html { allow all; }
location = / { root html; index index.html index.htm; deny all; }
location ~ \.html$ { allow all; }
}
</code>The
= /block matches only the root URI exactly; other URIs follow the normal literal‑then‑regex order.
Example 5 – Regex Order Depends on Definition Sequence
<code># Config 3.1
location ~ \.html$ { allow all; }
location ~ ^/prefix/.*\.html$ { deny all; }
# Config 3.2 (reversed order)
location ~ ^/prefix/.*\.html$ { deny all; }
location ~ \.html$ { allow all; }
</code>In Config 3.2, a request to
/prefix/regextest.htmlis denied because the first regex (the prefix‑specific one) matches and stops further searching.
Named Location with @
<code>server {
listen 9090;
server_name localhost;
location / { root html; index index.html index.htm; allow all; }
error_page 404 = @fallback;
location @fallback { proxy_pass http://www.baidu.com; }
}
</code>If a requested URI does not exist, Nginx internally redirects to
@fallback, which proxies the request to an external site.
Installation Note for the Rewrite Module
<code>wget http://nginx.org/download/nginx-1.4.6.tar.gz
tar zxvf nginx-1.4.6.tar.gz
./configure
make
make install
</code>If
./configurefails with
the HTTP rewrite module requires the PCRE library, install PCRE development packages (e.g.,
yum -y install pcre-devel openssl openssl-devel) or disable the module with
--without-http_rewrite_module.
Key Takeaways
Literal locations are evaluated before regular‑expression locations.
Exact matches (
=) and
^~prefixes stop further regex evaluation.
Regular‑expression locations are checked in the order they appear.
Named locations (
@) are used for internal redirects such as custom error handling.
The rewrite module depends on the PCRE library; ensure it is installed before configuring Nginx.
Raymond Ops
Linux ops automation, cloud-native, Kubernetes, SRE, DevOps, Python, Golang and related tech discussions.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.