Driver FixRecommendedSound, Wi-Fi or graphics acting up? Check drivers firstFind missing or outdated drivers fast.Check DriversHalloween DealsAmazon USHalloween week deals: useful picks before month-endAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run Scan×
Skip to content
VGSources
Blog

Apache Not Loading index.php on Ubuntu: A Complete Fix Guide

A practical Ubuntu troubleshooting guide for Apache requests that ignore index.php, show index.html or a directory listing, expose PHP source, or fail through PHP-FPM.
Length10 min Posted Quest giverVGSources Team
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

If Apache on Ubuntu shows index.html, lists a directory, downloads index.php, displays PHP source, or returns an error, the cause is usually one of four configuration breaks: the request is reaching a different virtual host, index.php is not in the active DirectoryIndex list, Apache has no PHP handler, or the site’s rewrite and permission rules are blocking the request. Follow the checks below in order. They identify the active site, prove that Apache can read the file, select the correct PHP integration (mod_php or PHP-FPM), and then verify the result from logs and a temporary PHP probe.

How Apache decides what to serve

A request for https://example.test/ does not automatically mean “run the index.php in the folder you edited.” Apache first selects a virtual host based on the address, port, and Host header. That virtual host supplies a DocumentRoot. The URL path is mapped below that root, and Apache checks the directory’s DirectoryIndex directive. Ubuntu’s documented default sequence includes index.html index.cgi index.pl index.php index.xhtml index.htm, but a site or distribution configuration can replace or reorder it. If no listed file exists, Apache may show a directory listing when Indexes is enabled, or return a forbidden or not-found response.

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.

Even when Apache finds index.php, it must have a PHP request handler. With the Ubuntu module package, Apache loads PHP in its own worker process through libapache2-mod-php. With PHP-FPM, Apache passes PHP requests over FastCGI through mod_proxy_fcgi to a version-specific FPM socket or endpoint. A PHP file is only executed when one of those paths is active and working.

Match the symptom to the likely fault

What you see Most likely cause First check
The site displays index.html instead of the application index.html appears before index.php in DirectoryIndex, or the request reached another virtual host Run sudo apachectl -S, then inspect the active DirectoryIndex
A directory listing appears No configured index file exists in the selected directory and Options Indexes is enabled Verify the exact DocumentRoot and file name, then disable listing with Options -Indexes if appropriate
The browser downloads index.php or displays its source No PHP handler is attached to .php requests Check for a loaded PHP module or an active FPM proxy configuration
HTTP 403 or “Forbidden” Apache cannot traverse a parent directory or read the file, or access rules deny the directory Use namei -l, test as the www-data user, and inspect the error log
HTTP 404 for a front-controller URL The application’s rewrite rules are not being read, or the request is mapped to the wrong root Check AllowOverride and mod_rewrite
HTTP 500 after enabling rewrites An invalid directive, unsupported .htaccess rule, or syntax error Run sudo apachectl configtest and read the Apache error log
HTTP 502, 503, or a gateway error with FPM The FPM service is stopped, the socket path is wrong, or Apache cannot access the socket Check the matching php*-fpm service, socket path, and both service logs

Step 1: confirm the virtual host and DocumentRoot

Start with the site Apache actually selected. From the server, run:

sudo apachectl -S
sudo grep -R 'DocumentRoot' /etc/apache2/sites-enabled/

apachectl -S lists listening addresses, name-based virtual hosts, and the configuration file that defines each one. Compare the hostname and port in your request with the matching VirtualHost entry. The DocumentRoot shown there—not the directory you happened to edit—determines which index.php Apache can see.

For a local test that bypasses DNS while preserving the virtual-host name, send the Host header explicitly:

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.
curl -i -H 'Host: example.test' http://127.0.0.1/

Replace example.test with the ServerName or ServerAlias in the intended site. If this response differs from the public URL, correct DNS, the virtual-host name, or the enabled-site links before changing PHP settings. A common mistake is editing /var/www/project while the enabled default site still serves another directory.

After identifying the root, verify the file beneath it:

sudo find /var/www/project -maxdepth 2 -type f -name 'index.php' -ls

Use the actual DocumentRoot in place of /var/www/project. Linux file names are case-sensitive: index.php, Index.php, and index.PHP are different names.

Step 2: prove that Apache can traverse and read index.php

Apache needs execute permission on every parent directory and read permission on the file. Inspect the complete path:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
namei -l /var/www/project/index.php
ls -l /var/www/project/index.php

Then test readability as Ubuntu’s usual Apache account:

sudo -u www-data test -r /var/www/project/index.php && echo readable
sudo -u www-data test -x /var/www/project && echo directory-traversable

Correct ownership and mode according to your deployment’s policy. A typical static web tree allows the web user to read files and traverse directories without granting everyone write access. Do not “fix” a 403 with chmod -R 777; world-writable web roots create a much larger security problem. If a parent directory is under a user’s home directory, its mode may prevent Apache from traversing it even when index.php itself is readable.

Also check Apache’s <Directory> rules. A broad Deny from all, an incorrect path, or an access-control directive inherited from another configuration can produce a 403 even with correct Unix permissions. The error log identifies which rule made the decision.

Step 3: inspect and correct DirectoryIndex

Find every active definition so that a later or more specific configuration does not surprise you:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
sudo grep -Rin '^[[:space:]]*DirectoryIndex' /etc/apache2

For a site that should prefer PHP, put index.php before competing files in the relevant virtual-host or directory context:

DirectoryIndex index.php index.html index.htm

If the application intentionally uses a static landing page, leave that order unchanged and request the PHP file explicitly. The directive only controls what Apache tries when the URL names a directory with a trailing slash; it does not change the mapping of an explicit /index.php request.

When no index file is found, Apache may generate a listing. To prevent that exposure in a site directory, use an appropriate directory rule such as:

<Directory /var/www/project>
    Options -Indexes
</Directory>

Place the rule in the virtual-host configuration or another context permitted by your server policy, validate it, and restart Apache:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
sudo apachectl configtest
sudo systemctl restart apache2

Choose one PHP integration path

Do not configure mod_php and PHP-FPM handlers for the same requests by accident. They have different process models, configuration files, and failure signals.

Characteristic Ubuntu Apache module (mod_php) PHP-FPM through FastCGI
Apache integration libapache2-mod-php loads a versioned PHP module into Apache mod_proxy_fcgi forwards PHP requests to FPM
Process model PHP runs inside Apache workers A separate FPM master manages PHP worker processes
Version and endpoint management Enable the matching versioned .load and .conf files under /etc/apache2/mods-enabled Use the running version’s service and its socket, commonly under /run/php/
Typical configuration action Install the module, enable it if absent, and restart Apache Enable proxy_fcgi, connect the virtual host to the matching FPM configuration or socket, and restart Apache
Typical failure signal PHP source is sent as text when no module is attached; Apache startup errors can occur after a bad module configuration 502/503 responses or “connection refused/no such file” messages when FPM or its socket is unavailable

Fixing mod_php on Ubuntu

Install and enable the Apache PHP module

Ubuntu’s supported package path is:

sudo apt update
sudo apt install php libapache2-mod-php

Check the installed command-line version and the Apache module files:

php -v
ls /etc/apache2/mods-enabled/php*.load /etc/apache2/mods-enabled/php*.conf

If the glob returns no files but a matching version exists under /etc/apache2/mods-available, enable that version. For example, if the installed package provides PHP 8.3, the command is:

sudo a2enmod php8.3

Use the version actually installed on your Ubuntu release; do not enable a module for a different PHP version. Check the configuration and restart:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
sudo apachectl configtest
sudo systemctl restart apache2

Do not rely only on php -v: that command reports the CLI binary, while Apache may still have a different or disabled module. The files in /etc/apache2/mods-enabled and Apache’s loaded-module list show what web requests use.

Verify execution with a temporary probe

Create a short file inside the active DocumentRoot:

echo '<?php phpinfo();' | sudo tee /var/www/project/phpinfo.php

Request it with the site’s real hostname:

curl -i http://example.test/phpinfo.php

A working handler returns an HTML PHP information page rather than source code or a download. Remove the probe immediately after testing because it reveals PHP version, paths, loaded extensions, and environment details:

sudo rm /var/www/project/phpinfo.php

Fixing PHP-FPM with Apache

Identify the installed FPM service and socket

PHP’s modern Apache deployment uses PHP-FPM with mod_proxy_fcgi. First discover the version instead of guessing a socket name:

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.
php -v
systemctl list-units --type=service 'php*-fpm.service'
ls -l /run/php/

Look for a service such as php8.3-fpm.service and a corresponding socket such as /run/php/php8.3-fpm.sock. The version must match. A stopped service or a socket left over from an uninstalled version cannot handle requests.

Enable the proxy integration

Enable the Apache modules and, where supplied by the Ubuntu package, the matching FPM configuration:

sudo a2enmod proxy_fcgi setenvif
sudo a2enconf php8.3-fpm
sudo systemctl enable --now php8.3-fpm
sudo apachectl configtest
sudo systemctl restart apache2

Replace 8.3 in these commands with the version you confirmed. If your virtual host uses an explicit handler instead of the packaged configuration, its PHP block must point to the same socket. A typical pattern is:

<FilesMatch '.php$'>
    SetHandler &quot;proxy:unix:/run/php/php8.3-fpm.sock|fcgi://localhost/&quot;
</FilesMatch>

Use the actual socket path. Keep only the handler model your site intends to use; a stale mod_php rule can intercept requests before FPM, while an FPM rule pointing to a missing socket produces gateway errors.

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

Check service health and socket permissions

sudo systemctl status php8.3-fpm
sudo journalctl -u php8.3-fpm --since '15 minutes ago'
sudo stat /run/php/php8.3-fpm.sock

Again, substitute the installed version. If the service will not start, its journal normally names the pool or configuration error. If FPM is running but Apache reports permission denied on the socket, inspect the socket owner and group and the FPM pool’s listening settings rather than changing permissions blindly.

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

Make .htaccess and front-controller routing work

Many PHP applications put rewrite rules in .htaccess so every request is sent to index.php. Apache ignores those directives when the corresponding directory has AllowOverride None. In the virtual host, set only the override classes the application requires. Rewrite rules need the FileInfo class; a DirectoryIndex directive in .htaccess needs the Indexes class. For example:

<Directory /var/www/project>
    AllowOverride FileInfo Indexes
    Options -Indexes
</Directory>

Enable rewriting and reload after validating:

sudo a2enmod rewrite
sudo apachectl configtest
sudo systemctl restart apache2

If the application needs other directives, add the narrowest additional override class rather than defaulting to unrestricted overrides. Confirm that the .htaccess file is in the directory Apache maps to the URL and that its name is exactly .htaccess. A 500 response immediately after enabling it usually means a directive is unavailable or malformed; the error log gives the line number.

Read the logs instead of guessing

Run the Apache error log while making one request:

sudo tail -f /var/log/apache2/error.log

In another terminal, request the page and note the exact status:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
curl -i http://example.test/
ls -1 /var/log/apache2/

The site may have its own access and error logs configured in the virtual-host file, so inspect those paths rather than assuming every request is in the global log. Useful clues include:

  • “File does not exist” indicates the URL mapped to a root where the file is absent, often because the wrong virtual host or DocumentRoot is active.
  • “client denied by server configuration” points to an Apache access rule, not a missing PHP package.
  • “AH01215” or PHP parse/runtime messages show that PHP was reached; fix the application or PHP configuration instead of changing DirectoryIndex.
  • “No such file or directory” for a Unix socket means the FPM socket path does not match the running version or service.
  • “Connection refused” usually means the FPM service is stopped or not listening at the configured endpoint.
  • “Invalid command RewriteRule” means mod_rewrite is not enabled or the directive is outside an allowed context.

For Apache service-level failures, also use:

sudo journalctl -u apache2 --since '15 minutes ago'
sudo apachectl -M | grep -E 'php|proxy_fcgi|rewrite'

The module list should reflect your chosen deployment: a PHP module for mod_php, or proxy_fcgi_module for FPM, with rewrite_module when the application needs rewrites.

Final verification sequence

  1. Run sudo apachectl -S and confirm the requested hostname maps to the intended virtual host.
  2. Read that virtual host’s DocumentRoot and verify the exact path, capitalization, ownership, and permissions of index.php.
  3. Inspect DirectoryIndex; put index.php before index.html only when PHP is the intended default.
  4. Choose mod_php or PHP-FPM. Do not leave a conflicting handler enabled.
  5. For mod_php, install libapache2-mod-php, enable the matching versioned module, run apachectl configtest, and restart Apache.
  6. For FPM, enable proxy_fcgi, connect Apache to the socket belonging to the running FPM version, verify the service, and restart Apache.
  7. If the application uses .htaccess, set the required AllowOverride classes and enable rewrite.
  8. Create a temporary phpinfo.php only to prove execution, then delete it.
  9. Record the HTTP status and read the Apache and, when applicable, FPM logs for the same request.

When these checks agree—the correct virtual host and root, a readable file selected by DirectoryIndex, one functioning PHP handler, permitted rewrite rules, and clean logs—Apache will execute index.php rather than serve a directory, static index, or raw source.

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.

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 quests from Patch Notes

  1. How to Set Up a RedM (RDR2) Server in 2026: License Key, txAdmin and server.cfg, Step by StepBlog11min
  2. Best RedM (RDR2) Server Hosting in 2026: Comparing Four Hosts on Slots, Memory and PriceBlog10min
  3. How to Host a Mindustry Server in 2026: server-release.jar, Port 6567 and the Commands That MatterBlog7min
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.