WordPress 500 Internal Server Error: Causes and Fixes
A 500 error hides its cause, but the server log does not. Where to find that log, how to test .htaccess, PHP limits and file permissions, and how to tell a 500 from a 502, 503 or 504.

A 500 response is the web server saying that something failed while it was building the page, and that it will not tell the visitor what. That is all a WordPress 500 internal server error means. The reason does exist, and it is written in a log on the server. Every fix here follows from reading that log, because one identical error page covers a broken .htaccess rule, a PHP crash, a permissions problem and a resource limit.
Work through the sections in order. The early checks are quick and easy to reverse, and the later ones touch more files. Before the first change, back up the files and the database, or at the very least download each file you are about to edit.
Make sure it is a 500 and not a 502, 503 or 504
The four codes look alike to a visitor and point to different places. Open the browser developer tools on the Network tab and reload, or run curl -I https://example.com/, and read the status of the page request.
| Status | Who is reporting it | Usual cause on a WordPress site |
|---|---|---|
| 500 Internal Server Error | The web server or PHP | A bad .htaccess directive, a PHP fatal error, wrong file permissions |
| 502 Bad Gateway | A proxy in front of PHP, such as nginx, a load balancer or a CDN | The PHP service crashed, is restarting or is not running |
| 503 Service Unavailable | The server, or WordPress itself | Maintenance mode, or the account reached a process or CPU limit |
| 504 Gateway Timeout | A proxy in front of PHP | The request ran longer than the proxy would wait: a slow query, a long import, a remote API that did not answer |
If the page says "There has been a critical error on this website", that is also a 500, sent by WordPress after it caught a PHP fatal error. Follow our guide to debugging the critical error message in that case. With a 502 or 504, leave .htaccess alone and look at slow code and the PHP service.
Read the server error log before you change anything
Hosting panels put the log in different places: under Metrics > Errors in cPanel, under Logs for the domain in Plesk, and under a similar name elsewhere. On your own server it is usually /var/log/apache2/error.log, /var/log/httpd/error_log or /var/log/nginx/error.log, with a separate log for PHP-FPM. Reload the failing page, then read the newest lines and match the time.
sudo tail -n 50 /var/log/apache2/error.log
What the common lines mean:
- "Invalid command" followed by a directive name, with
.htaccessin the path: Apache met a line it cannot process. Go to the.htaccesssection. - "not allowed here": the host does not permit that directive in
.htaccess. - "Request exceeded the limit of 10 internal redirects": a rewrite rule sends the request in a circle.
- "PHP Fatal error": a code problem. The path in the message names the plugin or theme.
- "Allowed memory size exhausted" or "Maximum execution time exceeded": a PHP limit.
- "End of script output before headers" or "Premature end of script headers": the PHP process died or was killed before it sent anything, typically because of a limit, a timeout or permissions.
- "Permission denied", or a complaint that a file is writable by group or others: permissions and ownership.
Test the .htaccess file
This applies to Apache and LiteSpeed. Nginx does not read .htaccess, so skip ahead if that is your server.
- Show hidden files in your SFTP client or file manager, and download a copy of
.htaccessfrom the site root. - Rename the file on the server to
.htaccess-offand reload the home page. - If the home page loads, the file was the cause. Inner pages will return 404 until the next step.
- Log in, open Settings > Permalinks and press Save Changes. WordPress writes a fresh file with its own block.
- Add the other blocks from your copy back one at a time (cache rules, redirects, security rules), reloading after each. The block that brings the 500 back is the faulty one.
The block WordPress generates for a site at the root of a domain is documented in the Apache section of the WordPress handbook and looks like this:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
The lines that most often break a site sit outside that block: php_value and php_flag lines on a host that runs PHP through FastCGI or PHP-FPM, directives for an Apache module that is not loaded and not wrapped in an IfModule test, rules left behind by a plugin that was removed, and typing mistakes from a hand edit.
Check PHP limits and timeouts
When the log shows a memory or time limit, raise the limit in the place your host supports. Most panels have a PHP settings screen. Where PHP runs as FastCGI or PHP-FPM, a .user.ini file in the site root does the same job:
memory_limit = 256M
max_execution_time = 120
PHP reads that file again every five minutes by default, so allow for the delay before you test, as the PHP manual explains in its page on .user.ini files. Do not copy these values into .htaccess as php_value lines unless you know the server uses the Apache PHP module. Anywhere else, those lines are themselves a cause of the 500.
A higher limit is a way to get the site back, not an explanation. If an import or a report needs more time than a web request allows, run it from WP-CLI or split it into batches. If ordinary pages run out of memory, something is loading far more data than it should.
Fix file permissions and ownership
The usual safe layout is 755 for directories and 644 for files, with wp-config.php tighter. Hosts that run PHP under your own account with suEXEC or a similar wrapper go further: they refuse to execute a script, or enter a folder, that is writable by group or by everyone, and answer with a 500. So setting everything to 777 "to be safe" both causes this error and opens the site to other accounts on the server.
Record the current state or take a backup first, then reset the tree over SSH:
find /path/to/site/ -type d -exec chmod 755 {} \;
find /path/to/site/ -type f -exec chmod 644 {} \;
Ownership matters as much as the mode. Files unpacked as root on a VPS belong to root, and the web server may be unable to read or write them. Which user should own the site depends on the server setup, so ask the host if you are unsure. The handbook page on WordPress file permissions explains the schemes.
Then plugins, the theme and core files
A "PHP Fatal error" line in the log already tells you which plugin or theme to deal with. Without a usable log, test by elimination. Over SFTP, rename the folder of the plugin you installed or updated last, for example wp-content/plugins/plugin-name to plugin-name.off, and reload. With no obvious suspect, rename the whole plugins folder for one page load to learn whether any plugin is involved, put it back, and narrow it down by halves as described in finding a plugin conflict.
For the theme, activate a default theme for a moment. For core, run wp core verify-checksums, or upload fresh copies of wp-admin and wp-includes from the same WordPress version. Core is the least likely cause, so it comes last.
Signs that a WordPress 500 internal server error is a hosting problem
Some patterns point away from your site. Images and CSS files return 500 as well as pages, even with .htaccess renamed, which rules out PHP and your own rules. The log is empty at the time of the error. The errors arrive in bursts at busy hours and vanish again, which suggests the account is hitting a limit on processes or memory. Or a copy of the same site runs cleanly on staging. Send the host the URL, the time, your IP address and any log line you have, and ask what the server recorded.
A developer is the right call when the fatal error sits in custom code, when the 500 hits checkout, enrollment or another page that earns money, or when 502 and 504 errors under load show the site needs profiling. That is the diagnostic side of our WordPress maintenance work, and where slow code is the root, of performance optimization.
Frequently asked questions
Why do I get a 500 error only in the WordPress dashboard?
The dashboard loads more code and uses more memory than a public page, so limits are reached there first. Plugins also run admin-only code that the front end never touches. Check the log for a memory line or a fatal error, and look for a separate .htaccess file inside wp-admin.
Why does the error appear only when I upload an image?
Resizing a large photo into several sizes takes a lot of memory and time, and the upload fails when either limit is reached. Scale very large images down before uploading, and check the log to see which limit was reached.
Is it safe to delete the .htaccess file?
Renaming it is safer than deleting it. WordPress recreates its own rewrite block from the Permalinks screen, but redirects, security rules and cache rules that were added by hand or by plugins are lost unless you kept the old file.
Can a 500 error hurt search rankings?
A short outage does no lasting harm, because crawlers come back and retry. Errors that go on for days are different. Search engines crawl a failing site less often and can drop pages that keep returning errors, so treat a persistent 500 as urgent.
Add worldwincoder.com as a preferred source on Google, or open this article in your AI assistant to use it as a source.
