Hardware FixRecommendedDevice not working? Your driver may be the problemCheck updates for common hardware issues.Fix DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix Now×
Skip to content
World desk12 min

Why Your Apache Virtual Host Isn’t Running PHP (and How to Fix It)

Find out why one Apache virtual host runs PHP while another downloads files, exposes source, or returns 502/503—and follow a precise vhost, handler, PHP-FPM and security troubleshooting path.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

When one Apache virtual host runs PHP but another downloads .php files, displays their source, or returns 502/503, the failure is usually in one of two places: Apache selected a different virtual host than you expected, or the selected host has no working PHP handler. Fix the selection first, then configure one PHP execution model—preferably PHP-FPM through mod_proxy_fcgi on Apache 2.4.

The quickest reliable path is to inspect the parsed vhost map with apachectl -S, send a request with the exact Host header, identify the PHP-FPM socket or port, and place a narrowly scoped handler in the vhost that actually receives the request.

As an Amazon Associate I earn from qualifying purchases.

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

1. Confirm Apache is using the virtual host you edited

PHP directives in a virtual-host block have no effect if the request is being handled by another block. Apache first chooses the best listening IP-and-port combination. For name-based virtual hosts on that listener, it compares the request’s Host header with each ServerName and ServerAlias. If no name matches, Apache uses the first vhost for that address and port as the default.

Read the parsed vhost map

Run:

apachectl -S

The output shows the address and port Apache is listening on, the default vhost, every ServerName and alias, and warnings about duplicate names. Check all of these against the hostname you type in the browser. A duplicate ServerName or ServerAlias can make the first declaration win even though a later file appears to contain the correct PHP settings.

Check both HTTP and HTTPS listeners. A host defined on *:80 is not automatically the same host as one defined on *:443, and an address-specific vhost can take precedence over a wildcard address. Make sure the name is present in the correct TLS vhost as well as the plain-HTTP one if your test uses HTTPS.

Test the listener with an explicit Host header

Testing the IP directly can be misleading because the IP does not identify a name-based vhost. Send the hostname explicitly:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
curl -H "Host: example.test" -i http://127.0.0.1/

Use the actual listener address, port, and hostname for your installation. The response status and headers are useful, but the most important evidence is which vhost log receives the request. For HTTPS, perform the equivalent test against the TLS listener while preserving the intended hostname so certificate and name-based selection are tested together. If DNS still points elsewhere, this test lets you isolate Apache from DNS and the browser cache.

Give each vhost unambiguous logs

Use separate access and error logs for each site, or include %v in the log format so the server name is recorded with each request. Request a known missing path, such as /this-file-should-not-exist, and confirm which log records the 404. Then inspect PHP-related messages in that same vhost’s error log. If the request lands in another site’s log, stop changing PHP directives and correct the name, alias, address, port, or file ordering first.

A browser request can hide this mistake because two sites may share a stylesheet, index page, or redirect. A deliberately unique 404 response or a temporary marker in the intended document root makes the selected vhost obvious. Remove any temporary marker after testing.

2. Identify how PHP is supposed to execute

Apache can hand PHP files to an embedded module (mod_php) or forward them to a separate PHP-FPM process manager. These are different architectures and require different handlers. Do not copy a mod_php recipe into a PHP-FPM installation, or assume that a PHP-FPM socket will work without mod_proxy_fcgi.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Characteristic mod_php PHP-FPM with mod_proxy_fcgi
Process model PHP is embedded in Apache workers. PHP runs in a separate PHP-FPM process manager.
Apache MPM compatibility Typical non-ZTS builds require the prefork MPM. Works with threaded event or worker MPMs.
Operations PHP lifecycle is tied to Apache workers and restarts. PHP can be restarted and managed independently, with its own process controls.
Handler style SetHandler application/x-httpd-php for PHP files. SetHandler using a proxy:fcgi TCP endpoint or Unix socket.
Current deployment guidance Useful for existing compatible installations. Preferred by Apache and PHP documentation for modern deployments.

The preference for PHP-FPM is a project recommendation, not a requirement to migrate every legacy server immediately. First establish which model is installed and which Apache MPM is active.

Check loaded modules and the MPM

Inspect Apache’s loaded-module list using the module-list command supplied by your distribution, or the equivalent output from apachectl. You are looking for the PHP module when using mod_php, or for mod_proxy and mod_proxy_fcgi when using PHP-FPM. Also identify whether Apache is running prefork, worker, or event MPM. A non-thread-safe, non-ZTS mod_php build generally cannot be combined safely with worker or event; PHP-FPM avoids that limitation.

Do not enable both execution models casually. A global mod_php handler can intercept files before the vhost’s intended FPM rule, while a second proxy rule can make troubleshooting ambiguous. Choose one model for the host, remove or disable conflicting mappings, and then verify the effective configuration again.

3. Configure PHP-FPM in the selected virtual host

For Apache 2.4, PHP-FPM through mod_proxy_fcgi is the preferred integration. It provides process isolation, independent PHP restarts, and compatibility with threaded MPMs. The handler must point to the PHP-FPM endpoint used by your pool; do not substitute a path from another machine or distribution.

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

Use a TCP endpoint

A pool listening on TCP port 9000 can be wired with a real-file guard:

<FilesMatch ".php$">
    <If "-f %{REQUEST_FILENAME}">
        SetHandler "proxy:fcgi://127.0.0.1:9000"
    </If>
</FilesMatch>

Replace 127.0.0.1:9000 with the address and port configured in the PHP-FPM pool. The -f condition means Apache forwards only an existing regular file. That matters for front-controller applications: a request such as /index.php/products can execute the real index.php, while a nonexistent /products.php is not blindly sent to PHP.

Ensure the pool is actually listening on that interface and port. A pool bound to a Unix socket will not answer on TCP, and a pool bound only to a different address will produce a gateway failure. If several PHP versions are installed, each pool may use a different port; copy the endpoint from the pool serving this site rather than assuming that 9000 is universal.

Use a Unix socket

Many installations expose PHP-FPM through a Unix socket. The Apache form is:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<FilesMatch ".php$">
    <If "-f %{REQUEST_FILENAME}">
        SetHandler "proxy:unix:/run/php/php-fpm.sock|fcgi://localhost/"
    </If>
</FilesMatch>

Use the exact socket path created by your PHP-FPM pool. A socket that does not exist, is owned by an inaccessible user or group, or is blocked by filesystem permissions produces a gateway error rather than PHP output. The trailing fcgi://localhost/ portion is part of Apache’s Unix-socket syntax; retain it while changing the socket path to the one on your host.

When permissions are the problem, check the socket’s owner, group, and mode together with the account used by Apache. Changing permissions broadly can expose the socket to unintended processes; prefer the pool’s intended group relationship. A stale socket after a PHP-FPM restart can also indicate that Apache and the pool are using different configured paths.

Keep the rule in the right scope

Place the FilesMatch and SetHandler in the virtual host that apachectl -S and your logs prove is serving the request. A handler in a different vhost, or only in a global configuration file that is overridden elsewhere, explains why one site executes PHP while another downloads it.

Check path handling and front controllers

Some applications use FallbackResource or rewrite rules to send non-file routes to one front controller. A PHP handler that catches every filename-shaped URL before fallback routing can turn valid application routes into 404 or 500 responses. Restricting the handler with the file-existence test allows the fallback mechanism to process paths that are not real PHP files.

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

4. Configure mod_php only when that is your installed model

With mod_php, Apache must load the PHP module and map files ending in .php to the PHP handler. A typical mapping is:

<FilesMatch ".php$">
    SetHandler application/x-httpd-php
</FilesMatch>

The module must actually be loaded; merely adding SetHandler does not install or activate PHP. Confirm the module list, confirm that the PHP build is compatible with the active MPM, and put the mapping in the vhost receiving the request. If Apache runs event or worker MPM with a usual non-ZTS PHP build, use PHP-FPM instead of forcing mod_php into an unsupported combination.

If the module is loaded globally but only one host should execute PHP, check how the distribution’s configuration files apply handlers and whether a later vhost or directory rule changes the content handler. The effective behavior, not the location of the text you edited, is what matters.

5. Match the symptom to the failed layer

What you see Most likely cause How to verify and correct it
The wrong site’s HTML appears The hostname did not match, names are duplicated, or the request reached the default vhost. Run apachectl -S, send an explicit Host header, inspect per-vhost logs, and make names unique.
The browser downloads a PHP file or displays PHP source The selected vhost has no PHP handler, or the required PHP module/proxy module is not loaded. Confirm the selected vhost, inspect loaded modules, then add either the PHP-FPM SetHandler or the mod_php mapping appropriate to the installation.
A PHP URL returns 502 or 503 PHP-FPM is stopped or unreachable, the socket or port is wrong, or permissions prevent Apache from connecting. Read the selected vhost’s error log, check the PHP-FPM service and pool endpoint, and correct the configured TCP address or Unix-socket path and permissions.
Only one virtual host executes PHP The handler exists globally or only in another vhost. Put the handler in the vhost proven to receive the request, then repeat the explicit-Host test and log check.
Front-controller routes produce unexpected 404 or 500 errors A broad PHP handler catches nonexistent paths before FallbackResource or application routing can run. Guard the handler with -f and keep routing rules ordered so only real PHP files are sent to FPM.

6. Verify the complete request path before reloading

A configuration can be syntactically valid yet point at the wrong vhost or an unavailable PHP endpoint. Validate in this order:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  1. Validate Apache syntax. Run your distribution’s Apache configuration-test command, commonly apachectl configtest. Fix every reported error before attempting a reload.
  2. Recheck the vhost map. Run apachectl -S again and confirm the intended address, port, ServerName, aliases, default vhost, and absence of duplicate names.
  3. Confirm the PHP endpoint. Compare the SetHandler value with the active PHP-FPM pool’s TCP listener or socket. For mod_php, confirm the module is loaded and the MPM is compatible.
  4. Reload gracefully. Use the service-management command provided by your operating system for a graceful Apache reload. The exact command differs by distribution; do not assume one service name or unit exists everywhere.
  5. Make a minimal test request. Through the intended hostname, request a small PHP test file and inspect the status, response body, access log, and error log. A successful response proves that this vhost selected a handler; it does not prove every application dependency is healthy.
  6. Remove diagnostic files. If you used a phpinfo() script, delete it after testing. It exposes PHP, web-server, path, and environment details that should not be public.

Test a static file as well as PHP. If static content is served by the wrong document root, a successful PHP response may still be coming from an unintended host. Test a nonexistent PHP filename and a normal application route to verify that the real-file guard and fallback behavior both work.

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

7. Avoid insecure or overly broad PHP matching

PHP execution should be limited to scripts you intend to run. A greedy ProxyPassMatch or similarly broad regular expression can interpret a path such as /uploads/file.jpg/something.php as PHP, depending on path-info handling. If an attacker can upload content and then append a PHP-looking suffix, that mismatch can become an upload-to-code-execution route.

  • Prefer a FilesMatch rule with an existence check for ordinary script execution.
  • Keep upload directories outside the document root when practical.
  • Do not give upload directories a PHP handler.
  • If path info is required, validate the real script path and the path-info portion rather than relying on a greedy proxy pattern.
  • After changing rules, test both a legitimate PHP file and an uploaded or static-looking path that must remain non-executable.

Do not treat a 404 as proof that an upload directory is safe: verify that the response is not being forwarded to PHP and that the file cannot be interpreted through an added path segment. Keep the narrow rule in every vhost that exposes user-controlled files, not only in the primary site.

8. A compact decision path

  1. If the wrong HTML appears, solve vhost matching before touching PHP.
  2. If the right site appears but PHP is downloaded or exposed as text, install or enable the correct handler in that vhost.
  3. If the handler is PHP-FPM and the response is 502/503, verify the pool is running, the endpoint is exact, and Apache can access the socket or port.
  4. If the application uses front-controller routing, retain the real-file guard so nonexistent PHP-looking paths reach the application fallback instead of an unintended backend request.
  5. If the server is a new Apache 2.4 deployment, choose PHP-FPM with mod_proxy_fcgi unless a documented legacy requirement calls for a compatible mod_php setup.

Frequently Asked Questions

Why does Apache show my PHP source code instead of executing it?

The selected virtual host is serving the file without a PHP content handler, or the required PHP module and proxy modules are not loaded. Confirm the host with apachectl -S and an explicit Host header, then add either a PHP-FPM SetHandler or the mod_php mapping that matches your installation.

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

Why does one virtual host run PHP while another downloads it?

Apache may be selecting the default or another duplicate-named vhost, or the PHP handler may exist only in the working host. Compare ServerName, ServerAlias, address and port entries, and per-vhost logs; then place the handler in the vhost that actually receives the request.

What does a 503 or 502 mean after adding PHP-FPM?

Apache reached a proxy handler but could not communicate with PHP-FPM. Check that the pool is running, that the configured TCP port or Unix socket exists, and that Apache can access it. The selected vhost’s error log usually identifies an incorrect endpoint or permission failure.

Should I use mod_php or PHP-FPM?

For modern Apache 2.4 deployments, Apache and PHP documentation prefer PHP-FPM through mod_proxy_fcgi. It supports event and worker MPMs, isolates PHP processes, and allows independent PHP restarts. Keep mod_php for a compatible legacy setup, normally with prefork MPM and a non-thread-safe PHP build.

Why do front-controller URLs return 404 after I configure PHP-FPM?

A broad handler may be forwarding nonexistent .php-looking paths before FallbackResource or rewrite routing can handle them. Wrap the handler in an existence test such as -f %{REQUEST_FILENAME} so only real PHP files are sent to FPM.

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.

Is a PHP handler in the global Apache configuration enough?

Not necessarily. Another vhost may be selected, or a later rule may override the global setting. Prove the receiving vhost with logs and apachectl -S, then verify the effective handler in that vhost.

How can I test a name-based vhost without changing DNS?

Send the intended name in the request’s Host header while connecting to the server’s IP, for example curl -H "Host: example.test" -i http://127.0.0.1/. Use the corresponding TLS listener and hostname when testing HTTPS.

The Bottom Line

Start with routing, not PHP: apachectl -S, an explicit Host header, and distinct vhost logs prove which configuration handled the request. Once that is certain, choose one execution model. On current Apache 2.4 systems, use PHP-FPM with mod_proxy_fcgi, point it at the real pool socket or port, guard the rule with a file-existence check, validate the configuration, reload gracefully, and remove diagnostic scripts. Keep upload paths non-executable and treat every 502, source response, or unexpected 404 as evidence from a specific layer to verify.

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.

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.

Leave a Reply

Your email address will not be published. Required fields are marked *

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

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.