A 500 Internal Server Error tells the visitor that something went wrong, but not what. The real message is always in a log. This guide shows where to look, how to recognise the common causes on an Apache server, and how to isolate the problem when the logs are not clear.
Before you start
- A Linux VPS running Apache 2.4 on Ubuntu, Debian, AlmaLinux or Rocky Linux.
- SSH access with
sudo. - A recent backup of the site files, or at least a copy of any file you plan to edit.
Step 1: Read the error log
Reload the failing page, then read the last lines of the error log at once, while the error is fresh:
sudo tail -n 30 /var/log/apache2/error.log # Ubuntu/Debian
sudo tail -n 30 /var/log/httpd/error_log # AlmaLinux/RockyIf the site has its own ErrorLog in the virtual host, read that file. If you run PHP-FPM, also check the FPM log, for example /var/log/php8.3-fpm.log on Ubuntu or /var/log/php-fpm/www-error.log on AlmaLinux.
The sections below match the most common messages.
Bad.htaccess directives
This is the most frequent cause. The log shows something like:
[core:alert] /var/www/example.com/public/.htaccess: Invalid command 'RewriteEngine', perhaps misspelled or defined by a module not included in the server configurationThe line names the file and the directive. Two common versions:
Invalid command 'RewriteEngine':mod_rewriteis not enabled. On Ubuntu and Debian, runsudo a2enmod rewriteand restart Apache. On AlmaLinux and Rocky it is loaded by default; check/etc/httpd/conf.modules.d/00-base.conf.Invalid command 'php_value':php_valueandphp_flagonly work withmod_php. Under PHP-FPM, remove those lines and put the settings inphp.inior a.user.inifile in the web root.
To prove .htaccess is the cause, rename it and reload the page:
sudo mv /var/www/example.com/public/.htaccess /var/www/example.com/public/.htaccess.bakIf the page loads (perhaps with broken links), restore the file and remove or fix the bad line.
Missing Apache modules
Directives such as Header, ExpiresActive or ProxyPass need their module. List what is loaded:
sudo apachectl -M | sortEnable a missing module on Ubuntu or Debian:
sudo a2enmod headers expires
sudo systemctl restart apache2On AlmaLinux and Rocky, most modules are loaded from /etc/httpd/conf.modules.d/. Some, such as mod_ssl, come as separate packages installed with dnf.
PHP fatal errors
When PHP crashes, Apache often returns a 500 with a blank page. The log shows a line such as:
PHP Fatal error: Uncaught Error: Call to undefined function mysqli_connect() in /var/www/example.com/public/db.php:4Common causes and fixes:
- Undefined function: a PHP extension is missing. Install it, for example
sudo apt install php8.3-mysqlorsudo dnf install php-mysqlnd, then restart PHP-FPM or Apache. - Allowed memory size exhausted: raise
memory_limitinphp.ini, or find the plugin that uses too much memory. - Syntax error after an edit: check the file with
php -l /path/to/file.php.
If you see nothing in the logs, make sure PHP logs errors. In php.ini set log_errors = On and keep display_errors = Off on a live site.
Permissions and ownership
Scripts that Apache cannot read, or a CGI script without execute permission, can cause a 500. On PHP-FPM, a socket that Apache cannot open produces errors such as AH01079: failed to make connection to backend. Check:
ls -l /run/php/
namei -l /var/www/example.com/public/index.phpFiles should normally be 644 and directories 755. Make sure the FPM pool's listen.owner and listen.group let Apache use the socket.
On AlmaLinux and Rocky, also check SELinux with sudo ausearch -m avc -ts recent. A denial there means a file label or boolean needs fixing, not a permission change.
Isolate the cause
When the log is unclear, narrow it down in this order:
- Serve a static file. Create
test.htmlin the web root. If it loads, Apache itself is fine and the problem is PHP or the app. - Serve a minimal PHP file:
echo "<?php echo 'ok';" | sudo tee /var/www/example.com/public/ok.phpIf ok.php works but the site does not, the problem is in the application code or its config.
- Disable plugins or modules in the app one at a time. For WordPress, rename the
wp-content/pluginsfolder. - Remove the test files when you finish.
Warning: Do not leave display_errors = On on a public site. Error messages can reveal file paths and database details to visitors.
Check it works
- Reload the page. It should return content, not the 500 page.
- Confirm the status from the command line:
curl -I https://example.com/should show200. - Tail the error log while you click around the site. No new errors should appear.
Troubleshooting
- Nothing in the Apache error log: the request may be handled by a different vhost with its own log, or by PHP-FPM. Run
sudo apachectl -Sto find the right vhost, and read the FPM log. - 500 only after a plugin or theme update: the update introduced a PHP error. Roll it back or disable it, then check the PHP version it needs.
- 500 appears at random under load: PHP-FPM may be running out of workers or memory. Look for
max_childrenwarnings in the FPM log. Request exceeded the limit of 10 internal redirects: a rewrite rule loops. Fix the rule, often by addingRewriteCond %{REQUEST_FILENAME} !-f.
Next steps
- Learn your logs in depth: Find and read Apache access and error logs.
- Make
.htaccesswork correctly: Enable.htaccess and mod_rewrite in Apache. - WordPress-specific causes: Fix the WordPress critical error.
- If you need help with your server, open a ticket.
