Why does nginx always close the connection when I use "return 444", even if there are matching location blocks?

hedgie asked:

According to my understand of how nginx processes a request, the following nginx configuration should lead to all requests matching the prefix location /, and thus be served an HTTP/1.1 301 Moved Permanently response redirecting to the https version of the site.

  server {
    listen 80 default_server;

      location / {
        return 301 https://$host$request_uri;
      }
    
    return 444;
  }

However, that is not what happens:

$ curl localhost
curl: (52) Empty reply from server

nginx seems to favor returning 444 (which closes the connection) above responding with the expected redirect.

Obviously this specific example is easily solved by removing the return 444 statement, but my real life config files are dynamically generated with zero or more location blocks, and I’d prefer having the final "catch-all" return 444 to prevent nginx from serving its built-in welcome page. Why doesn’t this work?

My answer:


return appearing in a server block but not within any location is always processed before any location blocks are even looked at, in the phase NGX_HTTP_SERVER_REWRITE_PHASE.

You need to add this to a location block which matches anything not matched by your other location blocks. So all of your server blocks should have one or more location blocks, not zero or more.


View the full question and any other answers on Server Fault.

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.