13

I am looking at an nginx location block that has this symbol ^~ (caret followed by tilde) before the location block. What does it do? I am having a hard time googling for it.

location ^~ /realestate/ {
    uwsgi_pass 127.0.0.1:2340;
    include /etc/nginx/uwsgi_params;
}
4
  • 3
    Sadly, our search engine doesn't process the ^ character either, so it will be hard for future users to find this question. :( The ^ symbol is borrowed from regular expressions and is referred to as an anchor, specifically the "beginning of line" anchor. Here is a link to the official documentation, but this page has a table that helps to explain its usage better.
    – Andrew B
    Commented Mar 10, 2015 at 22:01
  • 1
    @AndrewB, last link is wrong completely. ^~ means "don't check regexp locations if this location is longest prefix match"
    – Alexey Ten
    Commented Mar 11, 2015 at 4:50
  • Match fro begin would be location ~ ^/path/
    – Alexey Ten
    Commented Mar 11, 2015 at 4:51
  • Well, I'm wrong about "completely wrong", but it's confusing that it uses word "pattern" for prefix string.
    – Alexey Ten
    Commented Mar 11, 2015 at 4:54

3 Answers 3

6

To add to Jon's answer and to correct Eric's misleading answer - the ^~ is NOT a regex match, it is a prefix match with a higher priority than regexes.

From the nginx documentation:

Regular expressions are specified with the preceding “~*” modifier (for case-insensitive matching), or the “~” modifier (for case-sensitive matching).

So, only the locations with ~ and ~* modifier will be treated as regular expressions.

To find location matching a given request, nginx first checks locations defined using the prefix strings (prefix locations). Among them, the location with the longest matching prefix is selected and remembered. Then regular expressions are checked, in the order of their appearance in the configuration file.

This means that nginx first processes the non-regex locations, i.e.

  • location = /foo/bar (if this matches, processing ends immediately)
  • location /foo/bar
  • location ^~ /foo/bar

From these rules the longest match is found and remembered. Now nginx would move to evaluating all of the regex locations. But, the important part, written in the documentation as well:

If the longest matching prefix location has the “^~” modifier then regular expressions are not checked.

This means that if the selected longest-prefix-location was location ^~ /foo/bar, the regex locations are skipped and the match returns.

If, however, the longest-prefix-location match is location /foo/bar, then regular expressions are evaluated and only if none applies, is the matched location used:

The search of regular expressions terminates on the first match, and the corresponding configuration is used. If no match with a regular expression is found then the configuration of the prefix location remembered earlier is used.

All of this put together, it's about the priority of matching:

1. `=`       Exact match, terminate immediately
2. `^~`      Longest-prefix-match (not regex!)
3. `~`, `~*` Regular expression case sensitive/insensitive
4. `/`       Longest-prefix-match

Numbers 2 and 4 use the exact same matching mechanism, the only difference is their priority against the regular expression matches.

3
^~  The defined location url must begin with this syntax

if that syntax is matched, then regular expressions will not be used. So in your case once the folder realestate is found, the search will stop.

But if you know the folder you want to access & do not want to use regex

location = /realestate/ {

may be a faster rule

0

^ is the start of a match on the uri ~ indicates a regular expression match

/realestate/ without an explicit end will match on a uri beginning with /realestate/ in this case when using a regex match

More explicitly if your intent is to match on /realestate/ exactly location = /realestate/ would be a faster more optimized match

If your intent is really something like

location ^~ /realestate/.* this might be a little more accurate way to represent it

4
  • 1
    How is this different from the previous answer?
    – RalfFriedl
    Commented Apr 1, 2019 at 6:25
  • 1
    The previous answer seemed inaccurate ^~ indicates a type of match and is not a requirement of matching in general, it is one method of matching. It is unclear referring to a match of a folder when in fact it's a match of part of a request path or uri. So my intent was to provide an accurate clearer answer which does on the surface seem similar. But the other answer could lead to multiple misunderstandings. 1. that the ^~ is required for a match. 2. that it is actually matching on folders versus the request. Commented Apr 1, 2019 at 13:28
  • 2
    This answer is misleading! The caret (^) in ^~ has nothing to do with the regex meaning of "match the start of a string". Instead, as the other answer has explained, the ^~ match operator instructs to stop processing other regex-paths if this pattern matches. The reason why it's important and distinct from the regular prefix-matching rule location /foo/bar {} is that this "default" rule has a lower priority than regex matches! So if you want to match a location by prefix and want that match to have a higher priority than regexes, use ^~. Commented Oct 3, 2022 at 10:28
  • Nice further clarification, thanks. Commented Oct 14, 2022 at 16:00

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .