Understand Nginx location matching order
Trace exact, prefix, and regex location selection, including the limits of the usual flat-configuration rule.
For locations at the same level, start with exact matches, remember the longest matching prefix, then consider regex locations unless that longest prefix has ^~. Query-string parameters are not part of location matching.
Follow the selection sequence
- An
=location that matches the normalized URI ends the search. - Nginx finds the longest matching prefix, including prefixes marked
^~. - If that prefix has
^~, same-level regex checks are skipped. - Otherwise, regex locations are checked in configuration order; the first match wins.
- If no regex matches, the remembered prefix is used.
| Form | Meaning |
|---|---|
location = /a |
Exact normalized URI match. |
location ^~ /a |
Prefix that skips regex checks when it is the longest matching prefix at that level. |
location ~ \.php$ |
Case-sensitive regex. |
location ~* \.(jpg|png)$ |
Case-insensitive regex. |
location /a |
Ordinary prefix, subject to later regex selection. |
A ^~ prefix is not globally stronger than every longer ordinary prefix. URI normalization, such as percent decoding and path cleanup, also means an exact match is not a byte comparison of the raw request target.
Trace a flat example
These diagnostic locations can be placed inside a test server:
location / { return 200 "root\n"; }
location /images/ { return 200 "images\n"; }
location ^~ /static/ { return 200 "static\n"; }
location ~ \.css$ { return 200 "css\n"; }
location = /favicon.ico { return 200 "favicon\n"; }
| URI | Selected location |
|---|---|
/favicon.ico |
Exact favicon location. |
/static/style.css |
The longest prefix is ^~ /static/; the CSS regex is skipped. |
/images/style.css |
The CSS regex overrides the ordinary /images/ prefix. |
/images/cat.jpg |
The /images/ prefix remains selected. |
Regexes are tested in their listed order, not ranked by apparent specificity. Put a necessary narrow regex before a broader one, and test the overlapping paths.
Treat nesting and internal redirects separately
Nested locations make the flat shorthand incomplete. Nginx descends into the selected prefix's nested locations, and outer-level regex checks can still matter as the search returns. In particular, a nested ^~ does not automatically shield a request from every ancestor's regex. Exact and named locations also have nesting restrictions. Prefer a flat layout when it expresses the route clearly; use a route matrix when nesting is necessary.
An index, try_files fallback, or rewrite can initiate an internal redirect and a new location search. The first selected location may therefore not be the one that generates the final response.
FAQ
Does root behave like alias?
No. root appends the URI to a filesystem prefix. A prefix alias replaces the matched location portion; regex aliases require their own capture-based mapping. Check the actual filesystem path independently of route selection.
How can I see which location handled a request?
In a test configuration, use distinct responses as above. A temporary add_header X-Location "images" always; is another option, but header inheritance can change when you add it. Remove diagnostic markers after testing. Debug logging is available on a suitably built Nginx installation.
Can collected access logs show the chosen backend?
Only if the format includes the required variables, such as $upstream_addr, plus a useful route marker where appropriate. DataKit log collection cannot reconstruct a route field that Nginx never recorded. Compare exact, prefix, regex, and internally redirected requests after each change.
Reference: Nginx location directive.
Contact us
Join the community
to join the community
Try Guance
Start online and pay only for what you use.
Get startedChoose a Guance plan