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
server {
listen 9090;
server_name localhost;
location / {
root html;
index index.html index.htm;
deny all;
}
location ~ \.html$ {
allow all;
}
}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
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; }
}Request curl http://localhost:9090/exact/match.html returns 404 because the exact literal location is matched first and prevents the regex from being evaluated.
Example 3 – Using ^~ Prefix
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; }
}Now any request starting with / (including /index.html) is stopped after the ^~ / block, so the regex no longer overrides it.
Example 4 – Using = Prefix
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; }
}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
# 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; }In Config 3.2, a request to /prefix/regextest.html is denied because the first regex (the prefix‑specific one) matches and stops further searching.
Named Location with @
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; }
}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
wget http://nginx.org/download/nginx-1.4.6.tar.gz
tar zxvf nginx-1.4.6.tar.gz
./configure
make
make installIf ./configure fails 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.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.
