124

My first time using Nginx, but I am more than familiar with Apache and Linux. I am using an existing project and when ever I am trying to see the index.php I get a 404 File not found.

Here is the access.log entry:

2013/06/19 16:23:23 [error] 2216#0: *1 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client: 127.0.0.1, server: localhost, request: "GET /index.php HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "www.ordercloud.lh"

And here is the sites-available file:

server {
    set $host_path "/home/willem/git/console/www";
    access_log  /www/logs/console-access.log  main;

    server_name  console.ordercloud;
    root   $host_path/htdocs;
    set $yii_bootstrap "index.php";

    charset utf-8;

    location / {
        index  index.html $yii_bootstrap;
        try_files $uri $uri/ /$yii_bootstrap?$args;
    }

    location ~ ^/(protected|framework|themes/\w+/views) {
        deny  all;
    }

    #avoid processing of calls to unexisting static files by yii
    location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
        try_files $uri =404;
    }

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    location ~ \.php {
        fastcgi_split_path_info  ^(.+\.php)(.*)$;

        #let yii catch the calls to unexising PHP files
        set $fsn /$yii_bootstrap;
        if (-f $document_root$fastcgi_script_name){
            set $fsn $fastcgi_script_name;
        }

        fastcgi_pass   127.0.0.1:9000;
        include fastcgi_params;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fsn;

        #PATH_INFO and PATH_TRANSLATED can be omitted, but RFC 3875 specifies them for CGI
        fastcgi_param  PATH_INFO        $fastcgi_path_info;
        fastcgi_param  PATH_TRANSLATED  $document_root$fsn;
    }

    location ~ /\.ht {
        deny  all;
    }
}

My /home/willem/git/console is owned by www-data:www-data (my web user running php etc) and I have given it 777 permissions out of frustration...

My best guess is that something is wrong with the config, but I can't figure it out...

UPDATE So I moved it to /var/www/ and used a much more basic config:

server {
    #listen   80; ## listen for ipv4; this line is default and implied
    #listen   [::]:80 default ipv6only=on; ## listen for ipv6

    root /var/www/;
    index index.html index.htm;

    # Make site accessible from http://localhost/
    server_name console.ordercloud;

    location / {
        root           /var/www/console/frontend/www/;
                fastcgi_pass   127.0.0.1:9000;
                fastcgi_index  index.php;
                fastcgi_param  SCRIPT_FILENAME  /var/www;
            include        fastcgi_params;
    }

    location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
            try_files $uri =404;
        }

    location /doc/ {
        alias /usr/share/doc/;
        autoindex on;
        allow 127.0.0.1;
        deny all;
    }

}

Also if I call localhost/console/frontend/www/index.php I get a 500 PHP which means it is serving there. It just isn't serving off console.ordercloud ...

4
  • Another possible cause: If you are using php-fpm, make sure the user set in /etc/php-fpm.d/www.conf has permissions for the script it is trying to run. I think it defaults to apache.
    – Dave W.
    Jul 8, 2015 at 11:45
  • Another possible cause your SElinux is enabled, checkout SElinux config and disable it.
    – CK.Nguyen
    May 25, 2016 at 14:15
  • I just switched my Host Configuration from FCGId (run as virtual server owner) to FPM (run as virtual server owner). In addition to installing PhP 7.2-fpm, cli and more ... Jun 13, 2019 at 7:53
  • For me, include fastcgi.conf was missing. Dec 21, 2023 at 12:02

16 Answers 16

133

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.

17
  • 2
    This solve it for me; I was not aware that you had to prefix $document_root, I assumed it did that automatically, based on root.
    – b01
    Mar 14, 2014 at 14:32
  • 4
    Where can one learn more about the bad practice of setting the root within location? Jun 17, 2015 at 9:20
  • 25
    For those who don't understand exactly how the variable might be wrong: add to main Nginx http section the following: log_format scripts '$document_root$fastcgi_script_name > $request'; (or whatever you're feeding to SCRIPT_FILENAME), and to your server: access_log /var/log/nginx/scripts.log scripts. Reload and take a look at your new scripts log ;) Aug 30, 2015 at 22:53
  • 3
  • 7
    What is the yii_bootstrap?
    – Love
    Jun 1, 2017 at 6:42
74

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.

6
  • 5
    very nice! was that for me! Cheers mate! Aug 30, 2016 at 9:38
  • Thanks. For me the fpm/nginx docker containers I was running had permission issues accessing these folders.
    – Tek
    Nov 17, 2016 at 19:37
  • @Fleshgrinder's answer is wrong and yours is right! In my case it was, indeed, only a matter of correcting the ownership in the /etc/php/7.0/php-fpm.d/www.conf file. Cheers to you, bud. :) Many more people may start to see this issue also as vagrant popularity continues to grow.
    – user392778
    May 16, 2017 at 7:29
  • couldn't find anything inside /usr/local/etc/nginx/snippets/fastcgi-php.conf on my mac.. but i did find /usr/local/etc/nginx/fastcgi.conf
    – abbood
    Dec 31, 2017 at 0:29
  • Nice one!! Been struggling for hours
    – fonini
    Oct 9, 2019 at 20:40
10

"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.

9

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!

3
  • hello @we0, I have facing same issue with my setup. I have also running my another app on port 3001, so I have to host my php app on port 3002. you can see my original post here : stackoverflow.com/questions/33229867/… and stackoverflow.com/questions/33409539/… and another is stackoverflow.com/questions/33519989/…. Do you have any idea? Nov 26, 2015 at 6:28
  • 5
    Automatically making symlinks from sites-available to sites-enabled would be, well, undesirable. It's up to you to make those symlinks so that you can control which sites are 'on' and which are 'off' on your server.
    – Erathiel
    Aug 2, 2016 at 13:30
  • 1
    @Erathiel s/undesirable/nonsense. It's the main idea enable and disable them using these symlinks.
    – Artfaith
    Nov 9, 2020 at 16:34
9

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.

4

I did everything from above, lost 2 hours banging my head and problem still persisted. Finally I did:

sudo service php7.0-fpm restart

And viola it worked!

Btw, I was setting up fresh symfony 3.4 project with nginx conf from link: https://symfony.com/doc/3.4/setup/web_server_configuration.html

That was my fifth time of begining new symfony project and I couldn't believed this "Primary script unknown" is happening.

1
  • Very underrated answer. I was struggling a day trying almost all suggested solution, and wouldn't believe that just need to restart php to fix the error.
    – fsevenm
    Dec 23, 2022 at 13:23
3

I solved this problem by closing SELINUX in CentOS7.3 system

steps:

  • exec setenforce 0
  • U also need to modify config file

vim /etc/selinux/config set SELINUX to disabled

2

I had this issue also, and I solved it by exchanging the lines include fastcgi_params and fastcgi_param SCRIPT_FILENAME ....

Indeed nginx sets the last value of each FastCGI parameter, so you have to put your value after the default value included in fastcgi_params.

1

Check permissions for your php-fpm sock file, somehow it wasn't accessable :

chmod 755 /usr/local/var/run/php-fpm.sock

then try to restart nginx.

2
  • Also, consider verifying if php-fpm user shares nginx group. For example, sudo usermod -a -G www-data php-fpm if nginx runs as www-data and php-fpm runs as php-fpm.
    – Artfaith
    Nov 9, 2020 at 16:32
  • 3
    Do NOT use this method, you are basically introducing a security issue here. The command in the answer provide everyone read and write access to the socket. Apr 24, 2021 at 11:33
0

Try to add root directive within your php location.

location ~ \.php {
      root /home/willem/git/console/www;
      ...
}
8
  • 1
    The root directive should be set on a per server basis and shouldn't be used within any location blocks (unless you're a pro and want to circumvent some very special nginx bugs in your configuration). Oct 4, 2014 at 17:42
  • 1
    @Fleshgrinder one root per server is not best practice. Oct 3, 2015 at 2:58
  • @Fleshgrinder That's not what the section you linked says. The example of good practice in that section shows a root directive inside a location block.
    – user440728
    Jan 28, 2018 at 17:06
  • 1
    @Fleshgrinder What the pitfall is pointing out is that there should always be a root directive before the location blocks, so that no location is lacking a root. This is described in the text. It isn't written anywhere that multiple root directives can't be used, and it certainly doesn't say that the root directive shouldn't be used within any location blocks, as your first comment said.
    – user440728
    Feb 5, 2018 at 15:15
0

I found your question looking for the same error message but using apache + php-fpm (no nginx). For me, the problem was a slash in the wrong place: many setup suggestions include a line of the form:

SetHandler "proxy:unix:/path/to/file.socket|fcgi://localhost/:9000"

By placing the last slash after the port number like so:

SetHandler "proxy:unix:/path/to/file.socket|fcgi://localhost:9000/"

the problem dissappeared for me. Maybe you can do something similar

0

I've been trapped by this weird message for a very long time. I'm not sure about the cause because everything worked for a while then all of a sudden stopped working.

I was shortening wiki URLs as prescribed by MediaWiki, with Bitnami / Nginx on Lightsail.

Searched and read many posts, this one seems to summarize all possible scenarios, and I tried them all:

  • nginx is fine, root folder php is working, subfolder is not
  • error thrown as 404 + a bare string "File not found", not by nginx
  • add root to server, did not work
  • check permissions of folders and php-fpm / nginx, no problem root and subfolders are the same
  • check php-fpm manual for error code interpretation, could not find one
  • turn on php-fpm access log, found the request URI was correct, but 404 is returned
  • try to turn on verbose / debug mode for php-fpm, did not work, the supposed error log file is always empty

So I had to try the last resort, since root folder php was working and subfolders were not, the only major difference between them other than root is root folder used $request_filename and subfolder locations used $document_root and $fastcgi_script_name, so I changed subfolder location settings to match root folder ones.

Then it worked...I am still not sure why it worked. Because when I check php-fpm access log I see same URI, one was 404 and the other was 200.

enter image description here

The only difference was in the configuration. Since they produce the same output, I don't know why the result came out differently.

Anyway I decided to post my 2 cents here, hope this helps.

PS: I really do hope PHP provide better error messages and verbose mode, because this is really frustrating not being able to isolate the problem and no way to see verbose output and debug info.

0

To me it was extensions.

My php-fpm.www.access.log was reporting:

"GET /index.php5" 404

Yet the index file for the site (MediaWiki) was index.php. Turns out i had mixed extensions (php vs php5) in the relevant nginx.conf entries. Here's a working config:

location / {
    index index.php;
    try_files $uri $uri/ = @mediawiki;
}
location = /favicon.ico {
    return 204;
}
location ~ \.php$ {
    fastcgi_pass unix:/var/run/php-fpm.sock;
    include fastcgi_params;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME /path/to/viki$fastcgi_script_name;
    fastcgi_param DOCUMENT_ROOT /path/to/viki;
    fastcgi_intercept_errors on;
}

location @mediawiki {
    rewrite ^/([^?]*)(?:\?(.*))? /index.php?title=$1&$args last;
}

You can have all these entries use index.php5 instead, just add a index.php5 file to the root with this content:

<?php require './index.php';

(no closing tag).

0

Annother reason can be a missing semicolon (;) after the server_name

server_name domainurl.com
root /var/www/current/public;

which leads to a warning but no error!

-1

I meet the same question, But Other method didn't help me resolve the question!

I resolve it, I find the key is that: Linux User Right lead to the question: FastCGI sent in stderr: "Primary script unknown"

Because The PHP-FPM default user:group is apache:apache, But your code dir is someBody:someBody. So you should change the User right!

I write a blog to resolve this question, You can see this blog:

[Nginx FastCGI sent in stderr: "Primary script unknown"][1] ` [1]: http://geekhades.blogspot.com/2017/06/nginx-fastcgi-sent-in-stderr-primary.html

-1

I cloned a remote site, and the already existing wp-config.php had the remote server database info.

I resolved this issue by setting up my local wordpress config, with my local database info.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .