Don't process requests containing folders

Francis Daly francis at
Mon Sep 12 20:27:14 UTC 2016

On Mon, Sep 12, 2016 at 10:17:06AM -0700, Grant wrote:

Hi there,

> My site doesn't have any folders in its URL structure so I'd like to
> have nginx process any request which includes a folder (cheap 404)
> instead of sending the request to my backend (expensive 404).

The location-matching rules are at

At the point of location-matching, nginx does not know anything about
folders; it only knows about the incoming request and the defined
"location" patterns.

That probably sounds like it is being pedantic; but once you know what the
rules are, it may be clearer how to configure nginx to do what you want.

"doesn't have any folders" might mean "no valid url has a second
slash". (Unless you are using something like a fastcgi service which
makes use of PATH_INFO.)

> Currently I'm using a series of location blocks to check for a valid
> request.  Here's the last one before nginx internal takes over:
> location ~ (^/|.html)$ {
> }

I think that says "is exactly /, or ends in html".

It might be simpler to understand if you write it as two locations:

  location = / {}
  location ~ html$ {}

partly because if that is *not* what you want, that should be obvious
from the simpler expression.

I'm actually not sure whether this is intended to be the "good"
request, or the "bad" request. If it is the "bad" one, then "return
404;" can easily be copied in to each. If it is the "good" one, with a
complicated config, then you may need to have many duplicate lines in
the two locations; or just "include" a file with the good" configuration.

> Can I expand that to only match requests with a single / or ending in
> .html like this:
> location ~ (^[^/]+/?[^/]+$|.html$) {

Since every real request starts with a /, I think that that pattern
effectively says "ends in html", which matches fewer requests than the
earlier one.

> Should that work as expected?

Only if you expect it to be the same as "location ~ html$ {}". So:
probably "no".

If you want to match "requests with a second slash", do just that:

  location ~ ^/.*/ {}

(the "^" is not necessary there, but I guess-without-testing that
it helps.)

If you want to match "requests without a second slash", you could do

  location ~ ^/[^/]*$ {}

but I suspect you'll be better off with the positive match, plus a
"location /" for "all the rest".

Good luck with it,

Francis Daly        francis at

More information about the nginx mailing list