The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →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.
Antihost offers Linux VPS plans with full root access, unlimited traffic on a 1 Gbps port and a 14-day free trial.
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.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallEven 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.
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:
Rank #2
- Used Book in Good Condition
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:
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →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:
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problemssudo 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:
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.
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 "proxy:unix:/run/php/php8.3-fpm.sock|fcgi://localhost/"
</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.
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.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:
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
DocumentRootis 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_rewriteis 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
- Run
sudo apachectl -Sand confirm the requested hostname maps to the intended virtual host. - Read that virtual host’s
DocumentRootand verify the exact path, capitalization, ownership, and permissions ofindex.php. - Inspect
DirectoryIndex; putindex.phpbeforeindex.htmlonly when PHP is the intended default. - Choose mod_php or PHP-FPM. Do not leave a conflicting handler enabled.
- For mod_php, install
libapache2-mod-php, enable the matching versioned module, runapachectl configtest, and restart Apache. - For FPM, enable
proxy_fcgi, connect Apache to the socket belonging to the running FPM version, verify the service, and restart Apache. - If the application uses
.htaccess, set the requiredAllowOverrideclasses and enablerewrite. - Create a temporary
phpinfo.phponly to prove execution, then delete it. - 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.
Quick Recap
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.




