Debugging “Primary script unknown” Nginx FastCGI Error: Comprehensive PHP Configuration Guide


3 views

The error "FastCGI sent in stderr: Primary script unknown" typically occurs when Nginx cannot properly communicate with PHP-FPM to execute the requested script. This is fundamentally a path resolution problem between the web server and PHP processor.

Let's analyze the critical components in the configuration that need attention:

location ~ \\.php {
    fastcgi_split_path_info  ^(.+\\.php)(.*)$;
    
    # Path resolution logic
    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;
}

Here are the most frequent causes and their solutions:

1. Incorrect Document Root

Verify both Nginx and PHP-FPM are using the same document root:

# In nginx.conf
root /var/www/project/public;

# In php-fpm pool config (www.conf)
chdir = /var/www/project/public

2. Permission Issues

Instead of using 777 permissions, implement proper ownership:

sudo chown -R www-data:www-data /var/www/project
sudo find /var/www/project -type d -exec chmod 755 {} \;
sudo find /var/www/project -type f -exec chmod 644 {} \;

3. PHP-FPM Configuration

Ensure your pool configuration matches:

[www]
user = www-data
group = www-data
listen = 127.0.0.1:9000
listen.owner = www-data
listen.group = www-data
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3

Here's a proven configuration that resolves the issue:

server {
    listen 80;
    server_name project.local;
    root /var/www/project/public;
    
    index index.php index.html;
    
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    
    location ~ \\.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\\.php)(/.+)$;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}

Follow this diagnostic sequence:

  1. Verify file exists: ls -la /path/to/script.php
  2. Check Nginx error logs: tail -f /var/log/nginx/error.log
  3. Confirm PHP-FPM is running: sudo systemctl status php-fpm
  4. Test PHP-FPM directly: SCRIPT_FILENAME=/path/to/script.php REQUEST_METHOD=GET cgi-fcgi -bind -connect 127.0.0.1:9000

For complex setups:

  • When using Docker, ensure volume paths match between containers
  • For symlinked deployments, set realpath_root in Nginx
  • With SELinux enabled, check context: ls -Z /path/to/script.php

When migrating from Apache to Nginx, the "Primary script unknown" error often catches developers off guard. The error message in your logs indicates Nginx successfully passed the request to PHP-FPM, but the FastCGI processor couldn't locate the actual script file.

From your configuration, I notice several potential issues:

# Problematic original configuration
fastcgi_param  SCRIPT_FILENAME  $document_root$fsn;
# While $document_root points to /var/www/, $fsn may contain incorrect path

First, verify these critical elements:

# Correct PHP location block example
location ~ \.php$ {
    try_files $uri =404;
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_index index.php;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

Even with 777 permissions, SELinux might block access. Check:

ls -laZ /var/www/
ps aux | grep php-fpm
getenforce

Here's a proven configuration that works for PHP applications:

server {
    listen 80;
    server_name console.ordercloud;
    root /var/www/console/frontend/www;
    
    index index.php index.html;
    
    location / {
        try_files $uri $uri/ /index.php?$args;
    }
    
    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_intercept_errors on;
        fastcgi_pass unix:/run/php/php-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}

When troubleshooting:

# Check PHP-FPM pool configuration
grep -R "listen" /etc/php/*/fpm/pool.d/
# Verify Nginx and PHP-FPM user permissions
ps aux | grep -E 'nginx|php-fpm'

Developers often miss:

  • Mismatch between fastcgi_pass address and PHP-FPM listen address
  • Incorrect SCRIPT_FILENAME construction
  • Missing try_files directive in PHP location block
  • Path discrepancies between root directive and actual file location

Create a test PHP file:

echo "" > /var/www/console/frontend/www/test.php

Then access it via browser to confirm PHP processing works before debugging your application.