WordPress troubleshooting

500 Internal Server Error

The web server tried to produce the page, something went wrong inside, and it returned a status code instead of a reason.

500 Internal Server Error

Short answer

The reason is in the server's error log, not on the page. Read the last few lines of it before changing anything - a 500 caused by a malformed .htaccess and a 500 caused by a PHP fatal need opposite fixes.

Diagnosis

What causes it, most likely first.

Work down the list. Each check is written to rule its row in or out before you change anything, because the fixes below it are different and a guess costs more than a command.

CauseHow to checkFix
A malformed .htaccessRename the file and reload. If the 500 becomes a working page or a 404, .htaccess was the cause.Let WordPress write a clean one by re-saving permalinks. A directive from a plugin the server does not support is the usual reason.
A PHP fatal error the handler could not reportThe PHP error log has a "Fatal error" entry timed to your request, while the access log records the 500.Treat it as a fatal: find the named file, deactivate the plugin or theme that owns it.
Wrong file permissionsDirectories that are not 755 or files that are not 644, or anything group- or world-writable that the handler refuses to execute.Reset them. A restore from a backup that did not preserve modes is the usual cause of a whole tree being wrong at once.
A PHP extension is missing after a version changeThe error log names an undefined function rather than a syntax problem - a call to something the new PHP build does not provide.Install the extension or move back to the PHP version that had it. Switching PHP versions is when this appears.
The server ran out of a resource it does not nameThe 500 is intermittent under load and absent when the site is quiet.Look at process limits and memory before touching WordPress. An intermittent 500 is a capacity story, not a code story.
Walkthrough

Fixing it, step by step.

Commands assume WP-CLI and shell access. Where you have neither, each step says what it is doing so it can be done from the dashboard or over SFTP instead.

  1. Read the server error log first

    Everything else on this page is a guess until you have. The location varies; these two cover most stacks.

    tail -n 40 /var/log/nginx/error.log
    tail -n 40 /var/log/apache2/error.log
  2. Take .htaccess out of the picture

    One rename tells you whether rewrite rules are involved, without deleting anything.

    mv .htaccess .htaccess.off
  3. If that fixed it, have WordPress write a fresh one

    Re-saving permalinks regenerates the block WordPress owns and drops whatever else had accumulated.

    wp rewrite flush --hard
  4. Check permissions across the tree

    Directories executable, files not. Anything writable by the world is both a 500 risk and a security one.

    find . -type d ! -perm 755 | head
    find . -type f ! -perm 644 | head
  5. Confirm PHP itself is healthy

    If PHP cannot run a trivial file, the problem is below WordPress entirely.

    php -v && php -r 'echo "php ok\n";'
On MagicWP

What the platform takes off the list.

There is no .htaccess to malform - nginx owns the rewrites, and they are applied from configuration rather than from a file inside the web root that any plugin can append to. PHP versions are switched per site with the extension set that goes with them, so the missing-extension version of this error does not survive the switch, and the error log is one click from the dashboard rather than a path you have to guess.

FAQ

Questions, answered.

Why does the page not say what went wrong?
By design. A 500 is the status code for "something failed inside the server", and detail is deliberately withheld from visitors because it would describe your filesystem to strangers. The detail goes to the error log instead.
Is a 500 different from a white screen?
Yes, and the difference matters. A 500 means the server responded with an error status; a white screen usually means it returned 200 and an empty body. They point at different logs.
Everything works except one page. Can that be a 500?
Yes. A single template or a single plugin route can fatal while every other URL renders. Narrow it by the URL in the access log rather than assuming the whole site is affected.
Should I just raise the memory limit and see?
Not first. That fixes exactly one of the causes here and hides the others by changing timing. Read the log line before changing a value.
Related

If that was not it.

These fail in ways that look similar from the browser.