A 500 Internal Server Error is a generic "something broke" response. On your own server you have every log, so the real error is never far away. This guide is for VPS setups with Nginx or Apache and PHP-FPM; for shared hosting see the cPanel 500 error guide.
Before you start
- Root access and the exact URL and time of the error.
- Reproduce it once while watching the logs.
Watch the logs while you load the page
tail -f /var/log/nginx/error.log /var/log/php8.3-fpm.logFor Apache use /var/log/apache2/error.log (Debian/Ubuntu) or /var/log/httpd/error_log (RHEL). Also check the app's own log (Laravel storage/logs, WordPress debug.log). If PHP logs nothing, enable log_errors = On and catch_workers_output = yes in the FPM pool so worker errors reach the log.
Match the error to a fix
| Log shows | Fix |
|---|---|
PHP Fatal error: Uncaught Error ... / Parse error | Code bug or incompatible PHP version; fix or roll back the change |
Allowed memory size ... exhausted | Raise memory_limit or fix the code |
failed to open stream: Permission denied | PHP user cannot read or write a file; fix ownership |
Invalid command 'php_value' (Apache) | php_value in .htaccess only works with mod_php; move it to .user.ini |
Request exceeded the limit of 10 internal redirects | A rewrite loop in .htaccess or Nginx rules |
open_basedir restriction in effect | The script reads outside allowed paths; adjust open_basedir for the site |
Primary script unknown (Nginx) | Wrong root or SCRIPT_FILENAME; shows as 404 or 500 |
Fix file permissions
Code should be readable by the PHP-FPM user; only upload, cache and log folders writable:
find /var/www/site -type d -exec chmod 755 {} + && find /var/www/site -type f -exec chmod 644 {} +chown -R deploy:www-data /var/www/site/storage && chmod -R ug+rwX /var/www/site/storageCheck .htaccess (Apache)
Rename .htaccess temporarily. If the 500 disappears, the problem is inside: an unsupported directive, a missing module (a2enmod rewrite headers), or a rewrite loop. Restore it and remove lines one by one.
Check PHP-FPM and extensions
- Run
php-fpm8.3 -tto validate the configuration. - Confirm the site uses the PHP version you expect (
fastcgi_passsocket name). - Missing extensions show as
Call to undefined functionorClass not found; install them for that version and restart FPM.
SELinux on AlmaLinux and Rocky
If permissions look right but writes fail, check ausearch -m avc -ts recent. Label writable folders with semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/site/storage(/.*)?' and restorecon -Rv /var/www/site; allow outbound connections (APIs, remote database) with setsebool -P httpd_can_network_connect 1.
Check the fix
curl -I https://example.com/failing-pagereturns 200.- No new errors appear in the logs while you browse.
Troubleshooting
- 500 only after a deploy: missing
vendor(runcomposer install), cached config pointing to old paths, or a new required PHP extension. - 500 only for uploads: temp directory not writable or
upload_tmp_diroutsideopen_basedir. - Intermittent 500s: often resource-related (memory, max_children) or a flaky external service; correlate with timestamps.
500 error FAQ
Why don't I see the error in the browser?
Production hides PHP errors from visitors on purpose. They are in the logs.
Is a 500 the same as a 502?
No. A 500 is produced by the application or web server; a 502 means the proxy could not get a valid response from PHP-FPM at all.
Can a plugin cause a 500?
Yes, very often. The log names the file, which usually reveals the plugin or module.
