How to debug "FastCGI sent in stderr: Primary script unknown while reading response header from upstream" and find the actual error message?

PhpDebuggingNginxFastcgiStderr

Php Problem Overview


SO has many articles mentioning this error code:

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

That probably means that this error message is more or less useless.

The message is telling us that the FastCGI handler doesn't like whatever it was sent for some reason. The problem is that sometimes we have no idea what the reason is.

So I'm re-stating the question -- How do we debug this error code?

Consider the situation where we have a very simple site, with just the phpinfo.php file. Additionally, there is a very simple nginx config, as follows:

server {
    server_name testsite.local;

	root /var/local/mysite/;
 
    location / {
        index index.html index.htm index.php;
    }
 
    location ~ \.php$ {
        include /etc/nginx/fastcgi_params;
        fastcgi_pass  fastcgi_backend;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}

How can we see output/log exactly what fastcgi_params got sent to the script?

How can we see the actual error message? In my case, I'm using php-fpm. It has no info in the log about this error. The logs do not append any rows for this error. Is there a verbose mode for php-fpm?

/var/log/php-fpm/error.log
/var/log/php-fpm/www-error.log

I've tried to set this in the php-fpm.conf file

log_level = notice

and this in the php-fpm.d/www.conf file:

catch_workers_output = yes

Php Solutions


Solution 1 - Php

To answer your question:

  1. in php-fpm.d/www.conf file:

set the access.log entry:

access.log = /var/log/$pool.access.log

2. restart php-fpm service.

  1. try to access your page

  2. cat /var/log/www.access.log, you will see access logs like:

`- - 10/Nov/2016:19:02:11 +0000 "GET /app.php" 404

    • 10/Nov/2016:19:02:37 +0000 "GET /app.php" 404`

To resolve "Primary script unknown" problem:

  • if you see "GET /" without a correct php file name, then it's your nginx conf problem.

  • if you see "GET /app.php" with 404, it means nginx is correctly passing the script file name but php-fpm failed to access this file (user "php-fpm:php-fpm" don't have access to your file, which trapped me for 3 hours)

Hope my answer helps.

Solution 2 - Php

For me it was a permission issue & I had to change user & group in php-fpm/www.conf

change values to your username & group _www e.g

user = aqib
group = _www

Solution 3 - Php

As request is processed by the php worker, you can trace the php worker to get the reason.

To make it easy to locate which worker process the request, set only one worker in php-fpm's conf file.

pm.max_children = 1
pm.start_servers = 1
pm.min_spare_servers = 1
pm.max_spare_servers = 1

Get php work pid with $ps -aef | grep -v grep | grep php

root     28879     1  0 Apr12 ?        00:00:02 php-fpm: master process (/etc/php-fpm.conf)
www      28880 28879  0 Apr12 ?        00:00:24 php-fpm: pool www

Then trace the work process with $ sudo strace -p 28880, and then do the request, and you will see the trace output like below

strace: Process 28880 attached
accept(10,

{sa_family=AF_UNIX}, [112->2]) = 4
poll([{fd=4, events=POLLIN}], 1, 5000)  = 1 ([{fd=4, revents=POLLIN}])
times({tms_utime=1388, tms_stime=1099, tms_cutime=0, tms_cstime=0}) = 1336709044
read(4, "\1\1\0\1\0\10\0\0", 8)         = 8
read(4, "\0\1\0\0\0\0\0\0", 8)          = 8
read(4, "\1\4\0\1\4U\3\0", 8)           = 8
read(4, "\17DSCRIPT_FILENAME/data/HQ/SC_Edu"..., 1112) = 1112
read(4, "\1\4\0\1\0\0\0\0", 8)          = 8
lstat("/data/www/public/st/mn/dst.php", 0x7ffce98d7170) = -1 ENOENT (No such file or directory)
stat("/data/www/public/st/mn", 0x7ffce98d9580) = -1 ENOENT (No such file or directory)
stat("/data/www/public/st", 0x7ffce98d9580) = -1 ENOENT (No such file or directory)
stat("/data/www/public", {st_mode=S_IFDIR|0774, st_size=4096, ...}) = 0
...

From the trace output, it shows script file /data/www/public/st/mn/dst.php not exit

Solution 4 - Php

The issue caused by Nginx's fastcgi_pass not right.

You can check the following:

Open file: /etc/php-fpm.conf (systemctl status php-fpm to find it) and find pid = after = is a path you need to compare with your path listen = in file /etc/php-fpm.d/www.conf 2 path have to the same location.

for example:

pid = /run/php-fpm/php-fpm.pid

listen = /run/php-fpm/php-fpm.sock;

My old path listen = /var/run/php-fpm/php-fpm.sock; and I changed to /run/php-fpm/php-fpm.sock; then restart php-fpm then it run well.

Solution 5 - Php

In my case, this error occurs because php-fpm could not find file according to $document_root, which is /etc/nginx/html

By setting

 location ~ \.php$ {
        root /var/www/html;
        fastcgi_index   index.php;
        ...
    }

PHP-FPM can now locate the file correctly.

Solution 6 - Php

Check the root's position and also the file existence under it, I met this error because of the Root path TYPO .

Solution 7 - Php

For me (Oracle Linux 7) it was SELinux that was preventing php-fpm from accessing the file. Red Hat and Centos users may find the same.

runing

sestatus

shows the status of SELinux, for me it was turned on causing the problem. I had tried and implemented all of the other suggested fixes but the error persisted.

I solved it by putting SELinux into permissive mode:

/etc/selinux/config

# cat /etc/selinux/config
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=permissive
# SELINUXTYPE= can take one of these two values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected.
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted

The rest of my minimal configuration: /etc/nginx/nginx.conf:

user  apache;
worker_processes  1;

events {
}
http {

        include mime.types;
        server {
                listen 80;
                server_name 111.222.111.222; #your ip address
                root /sites/demo;

                index index.php index.html;

                location ~ \.php$ {
                        # pass to php-fpm
                        include fastcgi.conf;
                        include fastcgi_params;
                        fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
                }

        }
}

Note: I changed the user to apache which is the user used by php-fpm

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

 The address on which to accept FastCGI requests.
; Valid syntaxes are:
;   'ip.add.re.ss:port'    - to listen on a TCP socket to a specific IPv4 address on
;                            a specific port;
;   '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on
;                            a specific port;
;   'port'                 - to listen on a TCP socket to all addresses
;                            (IPv6 and IPv4-mapped) on a specific port;
;   '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory.
;listen = 127.0.0.1:9000
listen = /run/php-fpm/php-fpm.sock

; Set listen(2) backlog.
; Default Value: 511
;listen.backlog = 511

; Set permissions for unix socket, if one is used. In Linux, read/write
; permissions must be set in order to allow connections from a web server.
; Default Values: user and group are set as the running user
;                 mode is set to 0660
listen.owner = apache
listen.group = apache
listen.mode = 0660

Note: I set listen.owner and listen.group to apache

The permissions on my files and folders are: /sites (root:apache drwxrwxr-x) /sites/demo (root:apache drwxrwxr-x) /sites/demo/index.php (root:apache .rw.rw.r..)

If you look at ps -aux | grep -E "php|nginx" you can see that all of the php-fpm pool processes and the nginx worker process are running as user apache.

If you look at the permissions for the socket file /run/php-fpm/php-fpm.sock you will see that it is owned by apache:apache and srw-rw----

Solution 8 - Php

For MacOs users, in case if someone encountered as in my situation:

I had started php service with:

sudo brew start php72

since I have used "sudo" permissions was different. I needed to stop and start php service without sudo.

sudo brew stop php72
brew start php72

Hope helps to someone.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Question101010View Question on Stackoverflow
Solution 1 - PhpShengjie YUView Answer on Stackoverflow
Solution 2 - PhpAqibView Answer on Stackoverflow
Solution 3 - PhpLF00View Answer on Stackoverflow
Solution 4 - PhpThanhView Answer on Stackoverflow
Solution 5 - PhpdeejiwView Answer on Stackoverflow
Solution 6 - PhpherbertDView Answer on Stackoverflow
Solution 7 - PhpAidanView Answer on Stackoverflow
Solution 8 - Phpİsmail AtkurtView Answer on Stackoverflow