Nginx map directive not matching rules

Solution 1:

I figured out the issue. I had multiples of such config files for each domain and since map is defined in http context the last one was overwriting the value of variables. I fixed it by suffixing the variable name in each config file, so that variables are unique:

map $request_uri $new_uri_5 {
    default DEFAULT;
    /shell http://shell.com;
    /lol http://lol.com;
}
map $request_uri $ret_code_5 {
    default 301;
    /shell 301;
    /lol 302;
}

server {
    listen 80;
    server_name TestDomain.com www.TestDomain.com testdomain.com www.testdomain.com;

    location / {
        add_header X-request_uri $request_uri;
        add_header X-new_uri $new_uri_5;
        add_header X-return_code $ret_code_5;

        if ($new_uri_5 = "DEFAULT") {
            return 301 https://ashfame.com$request_uri;
        }
        if ($ret_code_5 = 301) {
            return 301 $new_uri_5;
        }
        if ($ret_code_5 = 302) {
            return 302 $new_uri_5;
        }
    }
}

5 is the ID of this particular domain in my system.

Solution 2:

I've been experiencing the same issue on Nginx 1.12.2 -- map directive would not match any of the patterns, even the simplest and most trivial ones like /, and always used the default value.

The issue tuned out to be caused by the use of the $uri variable in the mapping. Some Nginx configuration was implicitly modifying the $uri from its original value by prepending /index.php prefix which caused the pattern mismatch. Such behavior of $uri is by design and the exact distinction between $request_uri and $uri variables.

The fix was to replace the URI variable in the Nginx config:

map $uri $result_var {
    # ...
}

with the following:

map $request_uri $result_var {
    # ...
}