bizarre 404 on nginx

by r3wt   Last Updated June 08, 2016 08:00 AM

i have a location block for / that passes any virtual paths to index.php as instructed on the nginx pitfalls page. i have been using this setup for some time now, but recently i have noticed that some url's with - in the path segment return 404 in nginx, meaning they never reach the php script. I'm not sure if its related to the - in the url or not. some routes work with it, others do not.

works: /profiles/recently-added

returns 404: /explore/puerto-rico /puerto-rico

server block:

server {
    listen 80;
    server_name example.com;
    root /usr/share/nginx/hosts/www/;

    location ~ \.(php)$ {
        # commented out next 3 lines to see if that was the problem, but alas it made no change
        # try_files $uri = 404;
        # location ~ \..*/.*\.php$ {return 404;}
        # fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_keep_conn on;
        fastcgi_pass unix:/var/run/hhvm/hhvm.sock;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }

    location ~* .(png|gif|jpg|jpeg|ico|css|js)$ {
        include /etc/nginx/mime.types;
        expires 365d;
    }

    location / {
        include /etc/nginx/mime.types;
        index index.php;
        try_files $request_uri $request_uri/ /index.php?$query_string;
    }

}

I am struggling to understand what i've done wrong here. I've asked this question once before, and it was not well received. nginx version is from mainline branch, version 1.8.0



Answers 2


Clearly, issue is not nginx-related. Look for the problem on hhvm side, especially with existence of index.php where they should be to work on paths for URI

index index.php;

Maybe, you want to have rewritten URL's. Note, that .htaccess won't work - it's an apache feature. For nginx: http://nginx.org/en/docs/http/ngx_http_rewrite_module.html

GioMac
GioMac
November 20, 2015 16:15 PM

Bad location regex

The problem is this location regex:

location ~* .(png|gif|jpg|jpeg|ico|css|js)$ {
            ^

The period here does not mean only a period - it means any character. Thus it matches rico of puerto-rico. To match an actual period, it needs to be escaped:

location ~* \.(png|gif|jpg|jpeg|ico|css|js)$ {

Identifying problems without guessing

Using the debug log will remove the mystery of these problems. Applied to the config from the question (some lines omitted for brevity):

...
2016/06/08 12:38:58 [debug] 7056#7056: *133 http process request line
2016/06/08 12:38:58 [debug] 7056#7056: *133 http request line: "GET /puerto-rico HTTP/1.1"
2016/06/08 12:38:58 [debug] 7056#7056: *133 http uri: "/puerto-rico"
2016/06/08 12:38:58 [debug] 7056#7056: *133 http args: ""
2016/06/08 12:38:58 [debug] 7056#7056: *133 http exten: ""
2016/06/08 12:38:58 [debug] 7056#7056: *133 posix_memalign: 000000000229E060:4096 @16
2016/06/08 12:38:58 [debug] 7056#7056: *133 http process request header line
2016/06/08 12:38:58 [debug] 7056#7056: *133 http header: "User-Agent: curl/7.26.0"
2016/06/08 12:38:58 [debug] 7056#7056: *133 http header: "Accept: */*"
2016/06/08 12:38:58 [debug] 7056#7056: *133 http header: "Host: example.com"
2016/06/08 12:38:58 [debug] 7056#7056: *133 http header done
2016/06/08 12:38:58 [debug] 7056#7056: *133 event timer del: 7: 1465389598899
2016/06/08 12:38:58 [debug] 7056#7056: *133 generic phase: 0
2016/06/08 12:38:58 [debug] 7056#7056: *133 rewrite phase: 1
2016/06/08 12:38:58 [debug] 7056#7056: *133 test location: "/"
2016/06/08 12:38:58 [debug] 7056#7056: *133 test location: ~ "\.(php)$"
2016/06/08 12:38:58 [debug] 7056#7056: *133 test location: ~ ".(png|gif|jpg|jpeg|ico|css|js)$"
2016/06/08 12:38:58 [debug] 7056#7056: *133 using configuration ".(png|gif|jpg|jpeg|ico|css|js)$"
...
2016/06/08 12:38:58 [debug] 7056#7056: *133 http filename: "/var/www/puerto-rico"
2016/06/08 12:38:58 [debug] 7056#7056: *133 add cleanup: 0000000002301A48
2016/06/08 12:38:58 [error] 7056#7056: *133 open() "/var/www/puerto-rico" failed (2: No such file or directory), client: 127.0.0.1, server: example.com, request: "GET /puerto-rico HTTP/1.1", host: "example.com"
2016/06/08 12:38:58 [debug] 7056#7056: *133 http finalize request: 404, "/puerto-rico?" a:1, c:1
2016/06/08 12:38:58 [debug] 7056#7056: *133 http special response: 404, "/puerto-rico?"
2016/06/08 12:38:58 [debug] 7056#7056: *133 http set discard body
2016/06/08 12:38:58 [debug] 7056#7056: *133 xslt filter header
2016/06/08 12:38:58 [debug] 7056#7056: *133 HTTP/1.1 404 Not Found
Server: nginx/1.8.0
Date: Wed, 08 Jun 2016 12:38:58 GMT
Content-Type: text/html
Content-Length: 168
Connection: keep-alive

Shows what nginx was doing with the request. This line:

using configuration ".(png|gif|jpg|jpeg|ico|css|js)$"

Is the conclusive evidence that the request matched a location block you were not expecting, and would bring focus the the one rule that's in scope for the request.

AD7six
AD7six
June 08, 2016 12:45 PM

Related Questions


Set HTTP status code in response

Updated March 27, 2017 12:00 PM


Why does my 404 return 200 status code?

Updated April 17, 2018 03:00 AM