try_files ignored in combination with error_page and named locations

Džen yvldwt at
Wed Apr 4 08:48:01 UTC 2012

Thank you very much for your clarifying explanation. Seems like the only
thing missing was "recursive_error_pages on" for it to work like I
wanted it to have.

On 04/04/12 12:16pm, Ruslan Ermilov wrote:
> [...]
> First, this is a wacky config, and I don't quite understand what
> you're trying to achieve with it.  :)

Just to make you understand what I was trying to achieve with this
config: my maintenance page contains img tags pointing to images located
in $document_root. I used to add a simple

	try_files /$hostid-maintenance/ @backend;

to my configuration, but as expected a request to /foo.png returns the
contents of /$hostid-maintenance/index.html instead. Thus I was looking
for a solution to use a whole directory as an error page (being able to
request other files which are located inside the maintenance

> Here's what happens with the request of "/", assuming that "if"
> condition holds true.
> The status code is set to 503, and further processing happends in
> the named location @maintenance.
> It tries "$uri", find that directory, but because argument does
> not end with a slash (i.e., we're testing a file, not directory),
> this variant is ignored.

That's OK in my case, since the maintenance "environment" might contain
other directories.

> It then tries "$uri/", and succeeds.  $uri is set to
> "/$hostid-maintenance/".  As documentation of "try_files" says,
> the further processing is done in thi same (named) location.

I'm not really sure whether $uri is set to "/$hostid-maintenance/" if
"$uri/" is tried (since root is set to /var/nginx/$hostid-maintenance/
already). That works as expected and a request to / will actually just
try / relative to $document_root.

> What happens next is since a request now ends with a slash, the
> static module handler ignores it, and a request is processed by
> the index module.  The index module then verifies that the
> "/var/nginx/$hostid-maintenance/index.html" file exists and does
> an internal redirect to a new $uri.  (The fact that it does an
> internal redirect is also documented.)
> This in turn gets processed by the server's default location
> which is configured to return 503.  Because
> "recursive_error_pages" aren't enabled, the server ends up
> returning status code 503 with the standard content.

Thanks, that's what I forgot about.

> (What happens when you enable is left as an excercise to a
> reader.)
> When OTOH you request "/index.html", try_files checks that the
> _file_ exists, and the processing is performed by the static
> module in the context of location @maintenance.  There are no
> more internal redirects involved, so the server ends up sending
> you the status code 503 with the contents of index.html.
> I agree that this might not be obvious, but this is how it works.
> The important bit here is that requests that end up with "/", and
> get processed by the index module, do an internal redirect.  This
> is quite logical if you think about it, because they *usually*
> get processed by the static module, as if a request ended up with
> "/" followed by the name of index file.

Thanks again and kind regards


More information about the nginx mailing list