Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

A blank index.php page usually means NGINX reached the PHP-FPM handoff but PHP-FPM was given the wrong script path, the wrong socket, or a PHP error produced no visible output. An HTTP 200 OK does not prove that the intended file executed. Verify the active server block, document root, PHP-FPM endpoint, and SCRIPT_FILENAME in that order; then use NGINX and PHP-FPM logs to identify the remaining fault.

What a blank PHP page actually tells you

For a static file, NGINX can read bytes directly from disk. A PHP request takes a longer route: NGINX chooses a server block, maps the URI to a file or application route, sends FastCGI parameters to PHP-FPM, and returns the upstream response. A white page means that this chain did not produce visible body content. It does not identify which stage failed.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

NGINX’s FastCGI documentation describes SCRIPT_FILENAME as the parameter PHP uses to determine the script name, while QUERY_STRING carries request parameters. If the former points outside the deployed document root, PHP-FPM can receive a nonexistent file and still return an apparently successful response. The PHP bug tracker records the specific behavior: PHP-FPM can return status 200 with a blank page when the script does not exist. Treat the status code and the body as separate evidence.

  • Wrong file mapping: the root directive does not contain the deployed index.php, or SCRIPT_FILENAME constructs a different path.
  • Wrong upstream: fastcgi_pass names a socket or TCP address where PHP-FPM is not listening.
  • Routing mismatch: a rewrite or front-controller rule sends the request to a file that is absent or not intended for this virtual host.
  • PHP execution failure: a fatal error, missing extension, or application bootstrap problem occurs while error display is disabled.
  • Permissions or confinement: the PHP-FPM worker cannot traverse a directory or read the script, sometimes because of ownership, mode bits, ACLs, or a security policy.

Use this order so each test narrows the fault

Change one layer at a time. First establish which configuration NGINX actually loaded, then prove the file path, then prove the FastCGI endpoint, and only afterward debug application code. Keep a copy of the working configuration before editing it.

  1. Inspect the complete loaded configuration with nginx -T.
  2. Run nginx -t before reloading any change.
  3. Confirm the active root directory contains the deployed index.php.
  4. Check that the PHP location and fastcgi_pass match the running PHP-FPM service.
  5. Verify the exact SCRIPT_FILENAME that PHP-FPM will receive.
  6. Check existence, ownership, permissions, and any try_files or rewrite fallback.
  7. Read NGINX and PHP-FPM logs together.
  8. Compare direct and directory requests with curl -i.

1. Inspect the active server block and document root

Do not assume the file you edited is the file NGINX is using. Include files, a different virtual host, or a duplicate server_name can make an apparently correct edit irrelevant.

  1. Run sudo nginx -T. Search the output for the hostname you requested, every root directive, the index directive, and PHP locations.
  2. Identify the server block selected for the request. Check that its server_name, listen address, and port match the URL and whether the request uses HTTP or HTTPS.
  3. Locate the configured document root and list the entry file, for example with ls -l /path/to/document-root/index.php. Replace the example path with the value shown by your configuration.
  4. Confirm the server or inherited configuration contains index index.php (it may also list index.html). The index directive controls which file NGINX seeks when a URI ends in a slash.

When a client requests /, NGINX internally redirects the directory URI to a configured index file when that file exists. A missing or misplaced index.php therefore affects / even if a different PHP file can be requested directly.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

2. Validate syntax before changing behavior

Run:

sudo nginx -t

A successful test reports that the syntax is valid and the test is successful. If it fails, fix the named directive, missing include, certificate path, or permission issue before reloading. A configuration that has not passed nginx -t should not be put into service. After a successful test, reload rather than stopping the server:

sudo systemctl reload nginx

The exact service manager and privilege requirements vary by operating system. If your installation is not managed by systemd, use its documented reload mechanism.

3. Make the PHP location internally consistent

A typical PHP location has to perform three jobs: match PHP URIs, include FastCGI parameters, and send the request to the endpoint used by PHP-FPM. The following is a structural example, not a universal socket name:

location ~ .php$ {
    include fastcgi_params;
    fastcgi_pass unix:/run/php/php8.2-fpm.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

Check each line against your installation:

Directive What to verify Typical failure when it is wrong
location ~ .php$ The request is actually matched by this PHP location and is not intercepted by an earlier, more specific location. The request is served as a static file, redirected unexpectedly, or handled by a different upstream.
include fastcgi_params The included file exists and supplies the expected request parameters. PHP receives incomplete request metadata or a distribution-specific parameter set is omitted.
fastcgi_pass The Unix socket or TCP address is the endpoint on which PHP-FPM is listening. Connection refused, a missing socket error, or a request that never reaches PHP.
fastcgi_index The index name agrees with the application’s entry file. Directory requests resolve to an unexpected script.
fastcgi_param SCRIPT_FILENAME The resulting absolute path is the real script path visible to the PHP-FPM worker. “No input file specified,” a blank 200 response, or a PHP worker that cannot open the script.

Some distributions provide fastcgi.conf with a SCRIPT_FILENAME definition, while others use fastcgi_params and require you to add it. Inspect the included file rather than defining the parameter twice with conflicting values.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

4. Verify the PHP-FPM endpoint, not just the package

fastcgi_pass selects where NGINX sends FastCGI traffic. Installing PHP-FPM is not enough if the service is stopped or listening somewhere else.

Unix-socket deployments

For a socket configuration, check the path named in fastcgi_pass:

sudo systemctl status php8.2-fpm
ls -l /run/php/php8.2-fpm.sock

The service name and socket filename depend on the installed PHP version and distribution. If the socket is absent, inspect the PHP-FPM service status and its pool configuration. If it exists, ensure the NGINX worker can connect to it; the socket’s owner, group, and mode matter.

TCP deployments

A TCP form such as fastcgi_pass 127.0.0.1:9000; requires PHP-FPM to listen on that address and port. Check listening sockets with a platform-appropriate command such as:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
sudo ss -ltnp | grep 9000

Do not switch from a Unix socket to TCP merely because the example uses one. Use TCP when your topology needs a separate host, container, or network namespace, and restrict the listener appropriately; a PHP-FPM listener exposed beyond the intended trusted network is a security risk.

Recognize an endpoint mismatch

  • Connection refused: PHP-FPM may be stopped, bound to another address, or blocked by a local policy.
  • No such file or directory for a socket: the configured filename does not exist, often because the PHP version changed.
  • Intermittent upstream failures: workers may be exhausted or the service may be restarting; correlate timestamps with the PHP-FPM log.

5. Prove what SCRIPT_FILENAME resolves to

The common expression $document_root$fastcgi_script_name is correct only when both variables describe the same application layout. For a request to /index.php with a document root of /srv/www/site/public, the intended result is /srv/www/site/public/index.php. A root pointing at /srv/www/site instead would produce a different path.

Check the real file and every parent directory

  1. From the active server block, copy the exact root value.
  2. Append the script path represented by the request, such as /index.php.
  3. Run ls -l on that complete path and verify it is the deployed file, not a stale release or an empty placeholder.
  4. Check traversal permissions on each parent directory. A file can be world-readable while a parent directory prevents the PHP-FPM user from reaching it.
  5. If the application uses a symlinked release directory, verify where the symlink resolves and whether PHP-FPM’s security policy permits that target.

When the public document root is a subdirectory such as public, it must be the NGINX root; pointing NGINX one level above it can expose the wrong files and construct an invalid script path.

6. Use try_files correctly for direct scripts and front controllers

try_files can prevent NGINX from forwarding a nonexistent PHP file and can route application URLs to a front controller. Its behavior must match the application.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Direct PHP scripts

For a site where requested PHP files should exist physically, a guarded location can look like this:

location ~ .php$ {
    try_files $uri =404;
    include fastcgi_params;
    fastcgi_pass unix:/run/php/php8.2-fpm.sock;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

Here, a request for a missing script returns 404 instead of being handed to PHP-FPM. This makes a path error visible and avoids executing an unintended target.

Front-controller applications

Frameworks often send non-file URLs to one entry script. A common pattern is:

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

The fallback must name the actual entry file, and the PHP location must then resolve that file under the same document root. Do not add this pattern to a site that expects each URL to map to a separate script without understanding its rewrite rules; an incorrect fallback can create loops or hide a missing file.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

7. Read NGINX and PHP-FPM logs together

NGINX describes error_log as the record of errors and notes that its default location differs by installation. Use the active configuration to find the configured log path. If it is not obvious, nginx -V can show compiled-in paths and options.

  1. Make one request while watching the NGINX error log.
  2. Check the access log for the status, request URI, response size, and upstream timing fields if configured.
  3. Inspect the PHP-FPM service and pool logs for the same timestamp.
  4. Compare the first error after a fresh request, rather than a backlog from an earlier deployment.
Observed evidence Likely layer Next action
connect() failed, connection refused, or missing socket NGINX-to-PHP-FPM connectivity Confirm the service is running and make fastcgi_pass match its actual Unix socket or TCP listener.
“No input file specified” or a blank 200 body Script path or file visibility Recalculate SCRIPT_FILENAME, verify root, check the file, symlinks, and traversal permissions.
PHP fatal error, parse error, or uncaught exception Application/runtime Fix the named file and line, missing extension, dependency, or bootstrap error; keep diagnostics in logs.
404 before any PHP-FPM log entry NGINX routing or file existence Review location, try_files, rewrites, and the selected server block.
200 with zero or very small body and no obvious NGINX error PHP output or suppressed failure Inspect PHP-FPM logs, application logs, buffering, and the exact script being executed.

In production, leave display_errors disabled for visitors and send errors to a protected log. Temporarily enabling verbose errors can help on an isolated development system, but exposing stack traces or filesystem paths on a public site creates a separate security problem.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

8. Compare / and /index.php with curl

Use the same hostname and scheme that a browser uses:

curl -i https://example.test/
curl -i https://example.test/index.php

Compare the HTTP status, response headers, and body length. If /index.php is blank while a known static file returns correctly, static delivery is working and the fault is in PHP routing or execution. If both are blank, inspect the selected server block and upstream path first. If the direct script works but / does not, focus on index, directory resolution, and front-controller rewrites.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A browser may hide useful details by rendering an empty body as a white page. curl -i exposes headers, and adding -v can show connection and redirect behavior. Do not treat a 200 status, a successful TCP connection, or a loaded PHP-FPM service as proof that the intended script ran.

Choose the configuration that fits the deployment

Decision Option A Option B Choose based on
PHP-FPM transport Unix socket on the same host TCP address and port Use a socket for a conventional single-host deployment; use TCP when PHP-FPM is separated by a container or host boundary, with network access restricted.
Application routing Direct script execution try_files front controller Match the application’s filesystem and rewrite design. Do not use a fallback that hides missing scripts.
Error handling Verbose errors during isolated development Errors hidden from visitors and retained in logs Use the first only on a controlled environment; use the second for production security and observability.
Document root Application directory Dedicated public directory Point root at the directory that actually contains the public entry file; for frameworks, that is often a public subdirectory.

Common cases and targeted fixes

The site was moved to a new directory

Update the server block’s root, verify that the new path contains index.php, recalculate SCRIPT_FILENAME, run nginx -t, reload NGINX, and retest both URLs. Check for old release symlinks or a second virtual host still serving the previous path.

PHP was upgraded

PHP package upgrades commonly change the FPM service name and socket filename. Discover the socket supplied by the running service, then update fastcgi_pass to that exact endpoint. Do not retain an example such as php8.2-fpm.sock unless that is the version actually installed.

The browser shows blank output after a code change

Request the page once and inspect the PHP-FPM log immediately. A fatal error can produce no visible body when error display is disabled. Correct the reported code, dependency, configuration, or extension problem; changing NGINX directives will not repair a PHP exception.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Only rewritten URLs fail

Test /index.php directly. If it works, inspect the location / block, try_files fallback, query-string preservation, and any application base URL. Ensure the fallback points to the same entry file whose path is valid in the PHP location.

Permissions changed during deployment

Check the effective NGINX and PHP-FPM worker users, file ownership, directory execute permissions, ACLs, and mandatory-access-control denials where applicable. Grant only the read and traverse access required by the application; do not solve a read failure by making the entire tree world-writable.

When rebuilding the stack is reasonable

If the configuration repeatedly loses track of PHP versions, sockets, or document roots, moving to managed PHP hosting or a VPS with documented NGINX and PHP-FPM support can reduce operational work. Treat that as a deployment decision, not a fix for an unexamined path error: export the current configuration, identify the public document root, record the PHP version and extensions, and test the new endpoint before switching DNS. Socket names, package paths, permissions, and log locations still vary between providers and operating systems.

Final verification checklist

  • nginx -T shows the server block handling the requested hostname.
  • The active root contains the intended index.php.
  • The index directive includes index.php where directory requests need it.
  • nginx -t passes before every reload.
  • fastcgi_pass matches a listening PHP-FPM socket or TCP endpoint.
  • SCRIPT_FILENAME resolves to the real, readable script path.
  • try_files and rewrites match whether the application uses direct scripts or a front controller.
  • NGINX error/access logs and PHP-FPM logs show no corresponding path, connectivity, permission, or fatal-error message.
  • curl -i confirms the expected body for both / and /index.php.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.