After rewriting, nginx doesn't use php-fastcgi

Keelan asked:

I’m having trouble with an nginx rewrite. I want to rewrite ^(.*?)/(.*?)/?$ to controllers/$1.php?action=$2. This worked for me on an Apache server earlier. After that, I want to route that file to php-fastcgi.

For a normal request (i.e. when I type in the full path, without using a rewrite), php-fastcgi works normally.

My configuration:

server {
    listen [::]:80;

    root            /var/www/my-dir;
    index           index.php index.html index.htm;
    charset         utf-8;

    server_name         my-domain;

    location / {
        autoindex   off;
        rewrite     ^(.*?)/(.*?)/?$ controllers/$1.php?action=$2 last;

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_index   index.php;
        include     fastcgi_params;

    location ~ /\. {
        deny        all;

After editing this configuration, I did a service nginx restart, of course.

For some reason the location block for php-fastcgi isn’t used after the rewrite. Why is that & how to resolve it?

Instead, I’m getting a “No input file specified” as a response. In the error log, I see:

2013/06/01 19:00:25 [error] 14288#0: *1 access forbidden by rule, client: xxx, server: my-domain, request: "GET /user/create HTTP/1.1", host: "my-domain"

My answer:

You’re missing a try_files.

location / {
    try_files $uri $uri/ /index.php;
    # ....everything else

You might also have a problem with the rewrite since you don’t have a / at the beginning of the relative URL controllers/$1.php.... Try changing that to /controllers/$1.php....

And, you’re missing a fastcgi parameter that tells php-fpm where to find the PHP script. Add this into the location ~ \.php$ block.

fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;

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.