एरर समाधान · डेवलपर एरर

PHP-FPM Primary Script Unknown: Fix the nginx SCRIPT_FILENAME Path

Fix the nginx and PHP-FPM Primary script unknown error by correcting root, SCRIPT_FILENAME, try_files, chroot paths and file permissions. Includes tests.

Error messageFastCGI sent in stderr: "Primary script unknown" while reading response header from upstream

लेखक: SiteDownCheck संपादकीय टीम · अपडेट: अक्टूबर 28, 2026 · 4 मिनट पढ़ने में

Primary script unknown is what PHP-FPM reports when nginx (or another web server) asks it to run a PHP file and that file path does not exist, or cannot be read, from PHP-FPM's point of view. The browser usually shows a plain "File not found." page with HTTP status 404, and the nginx error log has:

FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client: 203.0.113.9, server: example.com, request: "GET /index.php HTTP/1.1", upstream: "fastcgi://unix:/run/php/php8.2-fpm.sock:", host: "example.com"

The web server and PHP-FPM are separate processes. nginx tells PHP-FPM which file to execute through the SCRIPT_FILENAME parameter. If that path is wrong, PHP-FPM answers "Primary script unknown." So the question is always: what path did nginx send, and does that path exist and is it readable by the PHP-FPM user?

Step 1: see the path nginx sends

Look at your fastcgi_param SCRIPT_FILENAME line (often inside include snippets/fastcgi-php.conf; or include fastcgi_params;). Then inspect the effective configuration:

sudo nginx -T 2>/dev/null | grep -nE "server_name|root |SCRIPT_FILENAME|fastcgi_pass|include .*fastcgi"

A common correct pattern:

server {
    server_name example.com;
    root /var/www/example.com/public;
    index index.php;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
    }
}

Distribution layouts differ: Debian and Ubuntu ship snippets/fastcgi-php.conf, while RHEL-style systems use include fastcgi_params; plus an explicit fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; line. Check the path and PHP-FPM socket name for your version.

Step 2: common causes

  1. root is missing or wrong inside the location ~ \.php$ block. If root is set only in another location, $document_root can be empty or a default folder. Put root at the server level.
  2. SCRIPT_FILENAME uses a literal wrong prefix, such as /scripts$fastcgi_script_name copied from an old tutorial.
  3. The file really does not exist. The request for /index.php has no file at $document_root/index.php. Confirm with ls -l /var/www/example.com/public/index.php.
  4. Permissions. PHP-FPM's user (usually www-data, nginx or a per-site user) cannot read the file or traverse parent directories. Test with sudo -u www-data test -r /var/www/example.com/public/index.php && echo ok. See PHP failed to open stream: Permission denied and nginx permission denied (13).
  5. chroot or containers with different paths. If PHP-FPM runs in a chroot, a container, or a different mount namespace, the path nginx sends (/var/www/...) may not exist there. Mount the same code at the same path in both containers, or set SCRIPT_FILENAME to the path as PHP sees it. In Docker setups, nginx and PHP containers need the same volume mapped to the same path or an adjusted fastcgi_param.
  6. try_files or rewrite rules sending nonexistent scripts, such as /index.php in a subdirectory when the app lives elsewhere, or a front controller that does not exist.
  7. security.limit_extensions in the PHP-FPM pool restricts which extensions may run. Default is .php; a request for .php5 or .phtml fails if not allowed. Check pool.d/www.conf.
  8. Wrong virtual host. A request is matched by the wrong server block and uses another site's root. nginx -T shows which blocks claim a name.
  9. Symlinks and deploy directories. Atomic deploys that swap a current symlink can briefly produce missing paths, or $realpath_root is needed so opcache sees the real path. Use fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; and fastcgi_param DOCUMENT_ROOT $realpath_root; for such deployments.
  10. SELinux denying PHP-FPM access; see the SELinux steps in the permission denied page above.

Step 3: test PHP-FPM directly

Make sure PHP-FPM itself is healthy and which socket it listens on:

sudo systemctl status php8.2-fpm
sudo ss -xlp | grep php
sudo grep -E "^(listen|user|group)" /etc/php/8.2/fpm/pool.d/www.conf

If nginx fastcgi_pass points to a socket that does not exist, you will get a connection error (502), not this message; see fix 502 Bad Gateway और nginx connect() failed (111). "Primary script unknown" means the connection succeeded, so the socket is correct and the path is wrong.

Create a test file to isolate the problem:

echo '<?php echo "ok ", __FILE__;' | sudo tee /var/www/example.com/public/t.php
curl -i https://example.com/t.php

If t.php works but /index.php does not, the application files are missing or unreadable. Delete the test file afterwards.

Apply and verify

sudo nginx -t && sudo systemctl reload nginx

Check the response with the HTTP स्टेटस चेकर; you want 200, not 404. Confirm headers with the HTTP Header Checker and keep an अपटाइम मॉनिटर on the home page so a bad deploy is flagged quickly.

अगले कदम

सामान्य प्रश्न

Why does the browser show only File not found?

PHP-FPM sends that text itself when the script path fails. The detail is in the nginx error log.

Does this mean PHP-FPM is down?

No. PHP-FPM answered. It is rejecting the file path nginx gave it.

I use Docker. What is the usual cause?

The nginx container and the PHP container do not share the same code path. Mount the same volume at the same location in both.

Is the problem in PHP or nginx?

Almost always the nginx configuration or filesystem layout, not PHP code.

Get notified when this fix updates

Plus occasional practical tips on uptime and monitoring, nothing else. Unsubscribe anytime.

यह पेज सामान्य जानकारी है, जिसे हमारी संपादकीय टीम ने लिखा है और दस्तावेज़ीकरण बदलने पर अपडेट किया जाता है। सर्वर और प्रदाता अलग-अलग होते हैं, इसलिए बदलाव पहले सुरक्षित तरीके से जाँचें। देखें: संपादकीय नीति और अस्वीकरण.