Nginx 1 FastCGI sent in stderr: “Primary script unknown”

Solution 1:

The error message “primary script unknown” is almost always related to a wrongly set SCRIPT_FILENAME in the nginx fastcgi_param directive (or incorrect permissions, see other answers).

You’re using an if in the configuration you posted first. Well it should be well known by now that if is evil and often produces problems.

Setting the root directive within a location block is bad practice, of course it works.

You could try something like the following:

server {
    location / {
        location ~* \.php$ {
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_pass 127.0.0.1:9000;
            try_files $uri @yii =404;
        }
    }
    location @yii {
        fastcgi_param SCRIPT_FILENAME $document_root$yii_bootstrap;
    }
}

Please note that the above configuration is untested. You should execute nginx -t before applying it to check for problems that nginx can detect right away.

Solution 2:

It's not always that the SCRIPT_FILENAME is wrong.
It may also be PHP is running as the wrong user/group.

This example is specific to Mac OS X, which in my experience is the most troublesome to setup (Debian is easy by comparison) - I've just upgraded from PHP 5.6 to 7.0, using homebrew and the excellent josegonzalez packages.

The problem was that a new copy of the config files was created.

The main config file is /usr/local/etc/php/7.0/php-fpm.conf, but note the Pool Definitions section at the end where it includes a whole subdirectory.

include=/usr/local/etc/php/7.0/php-fpm.d/*.conf

In php-fpm.d there's a www.conf file. By default this has:

user = _www
group = _www

On OS X, you may need to change this to:

user = [your username]
group = staff

(you should find this matches an ls -lh of your document_root)

Unfortunately without this change, you will still see this in your Nginx error log even if it's looking for the file in the correct place.

"Primary script unknown" while reading response header from upstream

Verify what it's currently running as:

ps aux | grep 'php-fpm'

or more cleanly:

ps aux | grep -v root | grep php-fpm | cut -d\  -f1 | sort | uniq

How to verify if the script filename is correct:

(stolen from igorsantos07 in the other answer)

Add to http block of main /usr/local/etc/nginx/nginx.conf:

log_format scripts '$document_root$fastcgi_script_name > $request';

(where the first bit needs to be whatever you're currently using, so you can see if it's right.)

And to use the log you've just defined, in your site's server block:

access_log /var/log/nginx/scripts.log scripts;

If it's correct, requesting example.com/phpinfo.php will produce something like this:

/path/to/docroot/phpinfo.php > GET /phpinfo.php

Can you simplify your existing config?

Are you using a location ~ \.php { block you copied/pasted from somewhere off the internet? Most packages allow you to do it more quickly and cleanly. e.g. on OS X you now just need this:

location ~ \.php {
    fastcgi_pass 127.0.0.1:9000;
    include snippets/fastcgi-php.conf;

    # any site specific settings, e.g. environment variables
}

Things like fastcgi_split_path_info, try_files and fastcgi_index (defaults to index.php) are in /usr/local/etc/nginx/snippets/fastcgi-php.conf.

That in turn includes /usr/local/etc/nginx/fastcgi.conf which is a list of fastcgi_param settings, including the crucial SCRIPT_FILENAME.

Don't ever duplicate root in the PHP location block.


Solution 3:

Ok, so 3 things I found after a day of struggling

  1. For some reason I had already something running on port 9000 so I changed to 9001
  2. My default site was intercepting my new one, once again I don't under stand why since it shouldn't, but I just unlinked it
  3. Nginx doesn't automatically do the sym link for sites-available to site-enabled.

Hope this saves someone some trouble!


Solution 4:

Had the same problem with a newer nginx (v1.8). Newer versions recommend using snippets/fastcgi-php.conf; instead of fastcgi.conf. So if you copy/pasted include fastcgi.conf from a tutorial, you might end up with the Primary script unknown error in the log.


Solution 5:

"Primary script unknown" is caused by SELinux security context.

client get the response

File not found.

nginx error.log has the following error message

*19 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream

so just change security context type of web root folder to httpd_sys_content_t

chcon -R -t httpd_sys_content_t /var/www/show




there are 3 users for nginx/php-fpm config

/etc/nginx/nginx.conf

user nobody nobody;  ### `user-1`, this is the user run nginx woker process
...
include servers/*.conf;

/etc/nginx/conf.d/www.conf

location ~ \.php$ {
#   fastcgi_pass 127.0.0.1:9000;  # tcp socket
    fastcgi_pass unix:/var/run/php-fpm/fpm-www.sock;  # unix socket
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
}

/etc/php-fpm.d/www.conf

[www]
user = apache  ### `user-2`, this is the user run php-fpm pool process
group = apache

;listen = 127.0.0.1:9000  # tcp socket
listen = /var/run/php-fpm/fpm-www.sock  # unix socket

listen.onwer = nobody  ### `user-3`, this is the user for unix socket, like /var/run/php-fpm/fpm-www.sock
listen.group = nobody  # for tcp socket, these lines can be commented
listen.mode = 0660

user-1 and user-2 are not necessary to be the same.

for unix socket, user-1 need to be the same as user-3, as nginx fastcgi_pass must have read/write permission on the unix socket.

otherwise nginx will get 502 Bad Gateway, and nginx error.log has the following error message

*36 connect() to unix:/var/run/php-fpm/fpm-www.sock failed (13: Permission denied) while connecting to upstream

and the user/group of web root folder (/var/www/show) is not necessary to be the same as any of these 3 users.

Tags:

Nginx

Php Fpm