A 500 Internal Server Error means the server hit a problem it couldn’t describe to the browser. With WordPress the cause is usually a PHP fatal error, a broken .htaccess (on Apache), resource limits, or permissions. On a VPS you have access to the logs, which turns guesswork into a quick diagnosis.
Step 1: read the error log (the real answer is there)
Nginx + PHP-FPM:
sudo tail -n 50 /var/log/nginx/error.log
sudo journalctl -u php8.3-fpm --since "1 hour ago" | tail -n 50
Apache:
sudo tail -n 50 /var/log/apache2/error.log
Then match the message to one of the causes below. See Nginx access and error logs.
Common causes
1. PHP fatal error (plugin, theme, code)
Log shows PHP Fatal error: … with a file path. Disable the plugin or theme in that path:
cd /var/www/example.com
wp --skip-plugins --skip-themes plugin deactivate plugin-name
Or rename its folder. (WordPress 5.2+ often shows “There has been a critical error” for these instead. See WordPress critical error.)
2. Broken .htaccess (Apache)
A bad rewrite rule, or a plugin directive your server doesn’t support (for example php_value with PHP-FPM), causes an instant 500. The log shows Invalid command or RewriteRule: bad flag.
mv .htaccess .htaccess.bak
If the site loads, regenerate it: Settings → Permalinks → Save. Then re-add custom rules carefully. See Apache .htaccess guide.
(Nginx ignores .htaccess. Rules must go in the server block. See the ideal Nginx config for WordPress.)
3. Memory limit
Allowed memory size of 134217728 bytes exhausted. Raise the limit:
// wp-config.php
define( 'WP_MEMORY_LIMIT', '256M' );
…and make sure PHP’s memory_limit allows it. See WordPress memory limit.
4. Timeouts
upstream timed out in the Nginx log usually gives a 504, but some setups return 500. Maximum execution time of 30 seconds exceeded comes from PHP. Raise max_execution_time and fastcgi_read_timeout sensibly, but also find out why the request is slow (a heavy plugin, an external API call, a slow query). See Nginx 504 gateway timeout.
5. File permissions and ownership
Permission denied in the log, or PHP can’t read files. Fix ownership and modes. See WordPress file permissions.
6. PHP-FPM not running or overloaded
A 502 is more typical, but check anyway:
systemctl status php8.3-fpm
server reached pm.max_children in the PHP-FPM log means all workers are busy. Tune the pool. See PHP-FPM tuning and Nginx 502 bad gateway.
7. Database problems
“Error establishing a database connection” is a separate message, but corrupted tables or a full disk can also surface as 500s:
df -h
wp db check
See error establishing a database connection and disk full troubleshooting.
8. Corrupted core files
After a failed update:
wp core verify-checksums
wp core download --force --skip-content --version=$(wp core version)
500 only in wp-admin, or on one page?
- Only wp-admin: usually a plugin hooking into admin, or a memory limit (admin needs more:
WP_MAX_MEMORY_LIMIT). - Only on save or upload: upload size or time limits, or a security module (ModSecurity) blocking the request. Check the log for the rule ID.
- Only on one page: a shortcode or block from a specific plugin.
Prevent it
- Update plugins on staging first, and keep backups. See update WordPress safely.
- Monitor uptime and error rates, so you notice before visitors do. See Uptime Kuma.
- Leave headroom in RAM and PHP workers. See WordPress VPS hosting.
Quick reference
| Log message | Likely fix |
|---|---|
PHP Fatal error … /plugins/X/ |
Disable plugin X |
Invalid command (Apache) |
Rename .htaccess, regenerate |
Allowed memory size exhausted |
Raise the memory limit |
Permission denied |
Fix ownership and permissions |
pm.max_children reached |
Tune PHP-FPM |
| Core file errors | wp core verify-checksums |
Related: WordPress debug mode and WordPress white screen of death.