1

In the following configuration snippet for nginx:

server {
        listen 443;
        listen [::]:433;

        ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

        server_name example.com;

        root /var/www/example.com;
        index index.html;
        error_page 502 = @fallback;
        error_page 404 = @not_found;

        location / {
            #try_files /index.html $uri =404; # A
            try_files $uri =404;              # B
        }

        location /service/ {
            rewrite ^/service/(.*)$ /$1 break;

            proxy_set_header X-Load-Balancer "a";
            proxy_set_header X-Real-IP $remote_addr;
            proxy_pass http://127.0.0.100:42424;
        }

        location @fallback {
            try_files /502.html =500;
        }

        location @not_found {
            try_files /404.html =500;
        }
}

Why does A correctly serve index.html (which is located in /var/www/example.com/) but B doesn't and results in the 404.html page being served instead?

2

The try_files directive processes each term in order, until it finds a file that exists.

If the file /var/www/example.com/index.html exists, the first term in case (A) will always be successful, and the URI will be internally changed to /index.html. The index directive is not involved. Also, case (A) will always return the /index.html file.

In case (B), try_files is looking for files only, and not directories. If you want try_files to match a directory and process it with the value of the index directive, use a term with a trailing /. For example:

try_files $uri $uri/ =404;

See this document for details.

5
  • Gotcha! I remember reading that the index directive works on URIs with trailing slashes, but I did not immediately understand that the actual serving was implemented by try_files. It makes sense. Thank you! – rrrrrrrrrrrrrrrr Sep 20 '18 at 19:12
  • 1
    You do not need try_files to implement index. But if you do have a try_files statement, you need to add the $uri/ term, otherwise index will be disabled within that block. – Richard Smith Sep 20 '18 at 19:18
  • Oh, ok. Is that specified in the documentation somewhere? – rrrrrrrrrrrrrrrr Sep 20 '18 at 20:49
  • Index is documented here. – Richard Smith Sep 20 '18 at 20:56
  • I really don't see how I would have gathered the information you provided from the documentation, which I had already read. – rrrrrrrrrrrrrrrr Sep 20 '18 at 21:06

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.