title: nginx: fallback to try_files when proxy_pass fails requires unusual config
body: <p>I am using Nginx to server a single page app. Basically we just need to serve the <code>index.html</code> page whenever no matching file is found. The location looks like this and has been working just fine:</p>
  
  <pre><code>location / {
     try_files $uri $uri/ /index.html
  }
  </code></pre>
  
  <p>Now I would like to query an upstream server, and only if that fails, use the <code>try_files</code> directive as above</p>
  
  <p>If the <code>try_files</code> is just moved to a fallback location like</p>
  
  <pre><code>location @fallback {
    try_files $uri $uri/ /index.html;
  }
  
  location / {
    proxy_pass http://127.0.0.1:8080;
    proxy_intercept_errors on;
    error_page 400 403 502 503 504 @fallback;
  }
  </code></pre>
  
  <p>then - when the upstream server is unavailable - the client sees the Nginx 502 error page instead of the files served from the file system.</p>
  
  <p>I finally found a solution that works by using a double slash in front of the /index.html fallback. This is the whole config file which can be used with the official nginx docker image for testing</p>
  
  <pre><code>events {
  } 
  
  http {
  
    error_log /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
  
    server {
  
      listen 80;
  
      root /usr/share/nginx/html/;
  
      location / { 
        proxy_pass http://127.0.0.1:9990;
        proxy_intercept_errors on; 
        error_page 400 403 502 503 504 = @fallback;
      }
  
      location @fallback {
        try_files $uri?$args /index.html //index.html;
      }
    }
  }
  </code></pre>
  
  <p>which can be run with a command like</p>
  
  <pre><code>docker run -v /path/to/www/folder:/usr/share/nginx/html:ro -v /path/to/config/nginx.conf:/etc/nginx/nginx.conf -d -p 8080:80 nginx
  </code></pre>
  
  <p>In case no double slash is present before the last <code>index.html</code> fallback like</p>
  
  <pre><code>location @fallback {
    try_files $uri?$args /index.html;
  }
  </code></pre>
  
  <p>Then nginx constructs a path on the filesystem like <code>&lt;root&gt;index.html</code>, which has a missing delimiter instead of the correct <code>&lt;root&gt;/index.html</code>, whenever a url which is not the root url is requested.</p>
  
  <p>Final question: why does this setup require a double slash within the try_files directive? Why can't one just use the try_files section from a regular config and move it to a fallback location used when intercepting errors?</p>