I'm having problem wrapping my head around routing processing in Nginx.

server {
    listen 80;
    listen [::]:80;
    server_name my_domain;

    root /var/www/ep;

    index index.html;

    error_page 403 404 /my403.html;

    location /images/ {
            try_files $uri @not_found;

    location @not_found {
            root /var/www/ep/not_found;
            try_files NON_EXISTENT_1 /not_found.jpg;

For above config, when I visit http://my_domain/images/xyz.png or http://my_domain/images/ I expect @not_found location directive to take place returning an image from /var/www/ep/not_found/not_found.jpg (it exists) but somehow /var/www/ep/not_found.jpg path is being tried (it doesn't exist). It results in displaying /my403.html file.

I want to use named location approach (@not_found).

Could somebody explain what's happening here?

Why /var/www/ep/not_found/not_found.jpg is not served?


You place /not_found.jpg at the end of the try_files statement, which makes it the URI term, which means nginx will search for a new location to process the request. You should make it not last, for example:

try_files /not_found.jpg =404;

See this document for more.

As an alternative to a named location, you could use:

location /images/ {
        try_files $uri /not_found.jpg;
location = /not_found.jpg {
    root /var/www/ep/not_found;

See this document for details.

| improve this answer | |
  • Thanks Richard for responding. I'm trying out this named location approach (I updated the question to make it visible) instead of "make it work somehow". I'm learning, I don't prefer quick fix. – lilly Aug 10 '18 at 11:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.