The “Unable to open primary script” error in nginx with PHP-FPM means nginx cannot find the PHP file that FastCGI was told to execute. The fix is usually correcting the fastcgi_param SCRIPT_FILENAME directive in your nginx server block, or fixing the file path and permissions so the PHP-FPM process can read the script. Below is a complete breakdown of why this happens and how to resolve it.
What Causes the Error
When nginx receives a request for a PHP file, it passes the request to PHP-FPM using the FastCGI protocol. PHP-FPM then tries to open the file specified in the SCRIPT_FILENAME parameter. If that path is wrong, or the file doesn’t exist, or the PHP-FPM user lacks read permission, you get the error. The exact message usually appears in your nginx error log as:
FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream
This is the same error as “Unable to open primary script”. It occurs before PHP even executes, so it’s not a PHP code problem—it’s a configuration or filesystem problem.
How nginx and PHP-FPM Work Together
nginx itself cannot execute PHP. It relies on a separate process (PHP-FPM) that listens on a TCP port (like 127.0.0.1:9000) or a Unix socket (like /run/php/php8.1-fpm.sock). When a request for a .php file arrives, nginx sends a FastCGI request that includes several parameters, most importantly:
SCRIPT_FILENAME– the absolute filesystem path to the PHP scriptSCRIPT_NAME– the virtual path from the URLDOCUMENT_ROOT– the web root directory
PHP-FPM uses SCRIPT_FILENAME to locate and open the file. If that path is incorrect, or if the file is missing, or if the PHP-FPM process user (often www-data) cannot read it, you get the error.
Step-by-Step Fixes
1. Check the SCRIPT_FILENAME Parameter
The most common cause is a missing or incorrect fastcgi_param SCRIPT_FILENAME line in your nginx configuration. In your server block or location block, ensure you have:
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
If you’re using a try_files directive, make sure it doesn’t rewrite the path before the FastCGI params are set. A common pattern is:
location / {
try_files $uri $uri/ /index.php?$query_string;
}
Then in the PHP location, use the same $document_root variable.
2. Verify the File Exists and Path is Correct
Check that the PHP file actually exists on the server at the path you expect. For example, if your document root is /var/www/html and the request is for /index.php, then $document_root$fastcgi_script_name becomes /var/www/html/index.php. Use ls -l /var/www/html/index.php to confirm.
If you use a symlink or a mounted volume, make sure the path resolves correctly for the PHP-FPM process. Sometimes nginx’s root directive is set to a relative path or a different directory than PHP-FPM’s chroot or chdir settings.
3. Check File Permissions and Ownership
PHP-FPM runs as a specific user (usually www-data on Debian/Ubuntu, nginx on RHEL/CentOS). That user must have read access to the PHP file and execute access to the directories in the path. Run:
sudo -u www-data ls -l /var/www/html/index.php
If you get a permission denied, change the ownership or permissions:
sudo chown -R www-data:www-data /var/www/html sudo chmod -R 755 /var/www/html
Be careful with chmod 777—it’s not secure. Use 755 for directories and 644 for files.
4. Check the PHP-FPM Pool Configuration
Each PHP-FPM pool (e.g., /etc/php/8.1/fpm/pool.d/www.conf) has settings for user and group. If these don’t match the nginx user, you may have permission issues. Also check chroot and chdir directives—if a chroot is set, PHP-FPM cannot access files outside that jail, even if nginx can.
5. Test with a Simple PHP File
Create a simple test file to isolate the problem:
echo '<?php echo "OK"; ?>' > /var/www/html/test.php
Then access http://your-server/test.php. If that works, the issue is with your specific script or routing. If it still fails, the problem is in the configuration.
Common Variations of the Error
Different Linux distributions and setups produce slightly different messages:
- “Primary script unknown” – the most common, from PHP-FPM
- “No such file or directory” – often means the path is wrong
- “Permission denied” – file exists but PHP-FPM can’t read it
- “File not found” – often appears in the browser when nginx can’t find the script
These all point to the same root causes: wrong path, missing file, or permission issues.
When the Error Appears Only for Certain URLs
If the error only happens for pretty URLs (e.g., /user/profile instead of /index.php?page=profile), the issue is likely with your try_files or rewrite rules. A typical fix for PHP frameworks (Laravel, Symfony, WordPress) is:
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
Make sure the PHP location block is not nested inside the first one, or you may get duplicate handling.
Comparing SCRIPT_FILENAME vs DOCUMENT_ROOT
Some configurations use fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; while others use fastcgi_param SCRIPT_FILENAME $request_filename;. Both can work, but $request_filename is derived from the root and alias directives, so it’s more reliable when using alias. If you have an alias in your location block, you must use $request_filename or manually set the path, because $document_root won’t include the alias.
Frequently Asked Questions
Why does the error say “Primary script unknown” in the logs?
That’s the exact message PHP-FPM sends back to nginx when it cannot open the file specified in SCRIPT_FILENAME. It’s the same as “Unable to open primary script” and has the same causes.
I changed the file permissions but still get the error. What else?
Check if SELinux or AppArmor is blocking PHP-FPM. On CentOS/RHEL with SELinux, run sudo setsebool -P httpd_can_network_connect 1 or check the audit log with sudo ausearch -m avc. On Ubuntu with AppArmor, check sudo aa-status for nginx or php-fpm profiles.
Does the error happen if the PHP file is outside the document root?
Yes, if you use fastcgi_param SCRIPT_FILENAME with a path outside the document root, PHP-FPM may not be able to access it unless the user has permission. Use alias or set fastcgi_param to the absolute path.
Why does it work with Apache but not nginx?
Apache uses mod_php which runs PHP inside the web server process, so it uses the same user and file permissions as Apache. nginx uses a separate PHP-FPM process with its own user, so permissions and paths can differ.
Is this error related to PHP version or nginx version?
No, it’s configuration-related, not version-related. The same fix applies across all recent versions of nginx and PHP-FPM.
Can I fix this by changing the PHP-FPM listen address?
No, the listen address (TCP vs socket) only affects how nginx connects to PHP-FPM. The error is about the script path, not the connection. However, if you change from socket to TCP, make sure the fastcgi_pass matches the new address.
Related
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.
More cards in this drawer
- Delete Picture Kik? How to Remove Photos
- Data Breaches That Shook the World
- Disable Google Assistant: Turn It Off on Android & Home
- Resin vs FDM Printers for Miniatures: Detail, Durability, Cost
- Are Networked Implants Safe? What If One Fails?
- How to Stop WordPress Comment Spam: A Layered Guide