A 500 Internal Server Error tells the visitor nothing useful by design — the real cause is always in Apache’s error log, and knowing where to look narrows it down fast.
# The error log almost always has the real reason sudo tail -50 /var/log/apache2/error.log # For PHP-specific errors, check PHP's own log too sudo tail -50 /var/log/php8.3-fpm.log # Test the config for syntax errors before assuming it's a code problem sudo apache2ctl configtest
Common Culprits
- A syntax error in a
.htaccessfile (checkAllowOverrideis even enabled to see it) - Wrong file permissions — Apache’s user (usually
www-data) can’t read a file it needs - A PHP fatal error with
display_errorsoff (correctly, for production) but not logged anywhere you’re checking - PHP-FPM socket path mismatch between the Apache vhost config and the actual running FPM pool
Temporarily enabling display_errors on a staging environment (never production) can speed up diagnosis, but the error log should always be the first stop — it captures errors even when display is off.