How to Fix the 500 Internal Server Error in WordPress (2026)

WordPress’s own crash screen is an HTTP 500. So is a blank white page. So is the unstyled page your web server serves when it gives up. Core’s fatal error handler hands a 500 response to wp_die() before it prints “There has been a critical error on this website.” The status code is identical in all three cases, so it tells you almost nothing. The page body tells you plenty. Who printed it cuts the list of causes roughly in half, before you touch a single file.

Quick answer: Read what rendered, not the code. A styled WordPress page means PHP ran, WordPress loaded, then a plugin or theme died. Check the site admin’s inbox for a recovery link. A bare server page with no WordPress styling means the request never got that far, so rename .htaccess and read the server log. A blank white page sits between the two, and the debug log settles it in about a minute.

Last reviewed: September 2026. Constants, memory defaults and PHP support dates verified against WordPress core documentation and php.net this month.

5 steps guide to Fix the 500 Internal Server Error on your site

Three Screens, One Status Code

Every guide opens with a list of causes. Corrupt .htaccess, plugin conflict, memory limit, permissions, and so on down the page. That list is accurate and close to useless, because you can’t tell from a status code which entry applies to you. Sorting by what rendered is faster.

A styled WordPress page. Grey background, small centered box, the sentence “There has been a critical error on this website” with a link to a WordPress support page. This is core talking. PHP started, wp-config.php parsed, WordPress booted far enough to register its shutdown handler, and then something threw a fatal error. Almost always a plugin, a theme, or code you pasted into functions.php. Jump to the recovery section.

A bare server page. Times New Roman on white, the words “Internal Server Error”, maybe an Apache or LiteSpeed version string at the bottom. Or your host’s own branded error page. WordPress never got a word in. The failure happened in the web server, in the PHP process manager, or in a config file the server read before handing anything to PHP. Start at .htaccess.

Nothing at all. A white page, no text, view-source shows an empty document. PHP died with error display switched off, and either the fatal came before WordPress could install its handler, or the handler itself couldn’t finish. Fatals inside wp-config.php, inside a must-use plugin, or in an opcache-stale file land here. So do out-of-memory kills, because PHP can run out of memory while trying to render the error about running out of memory.

One more screen gets confused with this constantly. “Error establishing a database connection” is not a 500. It’s WordPress reporting that MySQL refused it, and the fix lives in your database credentials, not in any of the files below.

What This Guide Checked, and What It Didn’t

Where a number appears in this guide, it came from whoever publishes it, checked in September 2026. Memory defaults and debugging constants come from the WordPress core documentation and from core’s own function reference. PHP behavior comes from the PHP manual, specifically the pages on per-directory INI files and on supported versions. Log locations come from each control panel’s official documentation rather than from a forum post quoting it.

We excluded three things on purpose. Advice that only works on one host is flagged as such rather than presented as general. Fixes that require database edits are out, because a 500 error almost never originates there and the risk is out of proportion. And any claim we could not trace to a vendor page or to core source was dropped instead of hedged.

The plugin-package failure described later was verified first-hand. We downloaded three release archives from WordPress.org, listed their contents, and compared them against the plugin’s own bootstrap file. Everything else here is documentation work. We did not reproduce each error on a live server, and we did not benchmark anything. We also can’t tell you which cause is statistically most common. Nobody publishes that data, and the guides claiming to know it don’t cite a source.

Confirm It’s Really a 500

Browsers paper over the difference between server errors. Chrome shows the same unhelpful page for several of them, and a cached copy can show you yesterday’s failure. Check the actual response header before you spend an hour on the wrong problem.

From a terminal, run curl -i https://yoursite.com. Use -i and not -I. The capital sends a HEAD request and throws away the page body, which is the half that tells you who printed the error. In a browser, open DevTools, go to the Network tab, reload, and click the top request. Either way you want the three-digit number, and it matters which one you get:

  • 500 means the server tried and something in your application broke. Nearly everything below applies.
  • 502 means a proxy in front (usually NGINX) got a garbage answer from the backend it was talking to. Often a PHP-FPM process that crashed or was never running.
  • 503 means the server is up and deliberately refusing. Overload, a maintenance mode, or a resource cap your plan hit.
  • 504 means the backend was reached but never answered in time. A slow query, a hung external API call, a cron job eating a worker.

The definition is blunt about why the first one is so vague. Mozilla’s HTTP reference describes 500 as a generic catch-all “indicating that the server cannot find a more appropriate 5XX error to respond with”. A server that knew what went wrong would have said so.

Two things worth ruling out in the same minute. Load the site in a private window. A service worker or an aggressive cache will happily serve a stored error page long after the site recovered. And try the front end and /wp-admin separately. A front end that loads while wp-admin throws 500 points somewhere specific, and we come back to that further down.

When WordPress Printed the Page

If you got the styled “critical error” page, WordPress already did most of the diagnostic work and tried to hand you the answer. Since version 5.2, core catches fatal errors and pauses whatever caused them. It then emails the address in Settings, General with a link into recovery mode. Follow that link and the broken plugin stays disabled for your browser session only. You can log in and remove it while visitors keep seeing the error page.

Check that inbox first, spam included. Then know why it so often arrives empty.

The WordPress documentation is candid about the failure mode. Plugins load in order. If the fatal fires before your SMTP plugin loads, the email goes out through the server’s own mail function instead. On a shared IP with no SPF alignment, that message gets filtered or dropped outright. The alert about your broken site is itself broken, by the same crash. You can’t fix that in the moment, but it does explain the missing email. Our guide to why WordPress stops sending email covers the deliverability side properly.

Getting the real error message

No email means you read the log instead. Two lines in wp-config.php, above the “stop editing” comment:

  • define( ‘WP_DEBUG’, true );
  • define( ‘WP_DEBUG_LOG’, true );

Core writes to wp-content/debug.log by default. Reload the broken page once, then open that file and read the last entry. A PHP fatal names the file and the line number, and the folder in that path is your culprit. That’s the whole diagnosis, and it takes longer to describe than to do.

Leave WP_DEBUG_DISPLAY alone while you do it, or set it to false explicitly. Printing errors to the screen on a live site publishes your absolute server paths to anyone reloading the page (and some people go looking for exactly that).

There’s a blunter instrument for the cases where the log stays empty. Adding define( ‘WP_DISABLE_FATAL_ERROR_HANDLER’, true ); switches off the handler entirely, so PHP’s own error surfaces instead of WordPress’s polite substitute. Core checks that constant in wp_is_fatal_error_handler_enabled(), and the effect is immediate. Use it for the thirty seconds it takes to read the message, then take it out. With the handler gone you also lose recovery mode, and every visitor sees the raw error.

Isolating the Plugin or Theme

You can’t click Deactivate on a dashboard you can’t reach. So do it from the filesystem. Core checks file_exists() on every active plugin before it loads any of them, and silently skips the ones that have gone missing.

Over FTP or your host’s file manager, rename wp-content/plugins to plugins-off. Reload the site. If it comes back, you’ve found the layer at fault.

Then do one thing before you rename the folder back, because the order matters more than any guide admits. Load /wp-admin first. Skipping on the front end and deactivating in the database are two different behaviors, handled by two different functions. The front end just skips. Only the admin side runs validate_active_plugins(), which calls deactivate_plugins() and actually writes the change. Rename the folder back without visiting the dashboard and all your plugins are still marked active, the broken one included. The site dies again the moment you do it, and it looks like the test proved nothing.

Once the dashboard has seen the empty folder, rename it back and re-enable plugins one at a time, reloading after each. The one that kills the site again is your answer. Same technique for themes: rename the active theme’s folder and WordPress falls back to a default one.

With SSH, WP-CLI does it in one command, and its global flags are the useful part. Running wp plugin deactivate –all with –skip-plugins boots WordPress without loading plugins at all. The fatal never fires, so the command completes. Note the documented limit: mu-plugins still load either way. A fatal in wp-content/mu-plugins survives both approaches, and that folder has to be moved by hand.

The May 2026 case that made this concrete

Plugin fatals usually come from a conflict, where two things that each work alone don’t work together. Sometimes the package itself is just broken, and one release from this year shows the mechanism cleanly.

Shortcodes Ultimate, a plugin active on 400,000 sites, shipped version 7.5.1 on 18 May 2026 with the bundled /freemius/ directory missing from the package. Line 31 of that version’s main file still called require_once on /freemius/start.php, with no file_exists check around it. We downloaded all three archives to confirm it. Version 7.5.0 holds 223 files under that folder, 7.5.1 holds none, and 7.5.3 restores 222. The broken archive is a megabyte smaller than the release on either side of it.

A require_once pointing at a file that isn’t there is a fatal error. Every request, every visitor, no exceptions. The author tagged the replacement, 7.5.3, the next morning on 19 May 2026. Its changelog entry is one line: “Fixed issue with missing /freemius/ folder”. Versions 7.5.1 and 7.5.2 no longer appear in the plugin’s tag list at all.

Two things follow from that for anyone reading a log right now. Blaming a conflict is a guess. A fatal that names a vendor path inside one plugin folder usually isn’t a conflict. And if the site died straight after an auto-update, rolling that plugin back one version is a fair first move, not a last resort. The broken thing may already have been withdrawn.

The .htaccess Fix, and the One That Backfires

This file is the first suspect when the server printed the error page, because Apache reads it before PHP is involved at all. One invalid directive in it returns 500 for every request to that directory and everything under it.

The repair is a rename, not an edit. Over FTP, rename .htaccess in your WordPress root to htaccess-old and reload. Site back? The file was the problem. Go to Settings, Permalinks in the dashboard and click Save Changes without altering anything, and WordPress writes a clean rewrite block. Site still broken? Rename it back and move on, because you’ve eliminated it.

Now the part that trips people up. Most 500-error guides tell you to raise your memory limit by adding a line like php_value memory_limit 256M to .htaccess. On a lot of hosting in 2026, that line is itself the 500.

Here’s the mechanism. php_value is a directive supplied by mod_php, the old model where PHP runs inside the Apache process. Hosts have largely moved to PHP-FPM or FastCGI, where PHP runs as a separate pool and mod_php isn’t loaded. Apache meets a directive no loaded module recognizes, refuses to serve the directory, and returns 500. The PHP manual states the split plainly. Per-directory INI files “are processed only by the CGI/FastCGI SAPI”, and Apache-module users are pointed at .htaccess for the same effect. Two mechanisms, and you need the one your host actually runs.

So which one have you got? Finding out takes a single file, and almost no guide tells you to look. Drop a file called check.php in your web root, containing one call to phpinfo(). Load it in a browser and read the Server API line near the top.

“Apache 2.0 Handler” is mod_php, so php_value works. “FPM/FastCGI” or “CGI/FastCGI” means it doesn’t. “LiteSpeed V” is the ambiguous one. That same string covers LiteSpeed Enterprise, which honors php_value, and OpenLiteSpeed, which takes rewrite rules from .htaccess and ignores the rest. On either, skip the question and use .user.ini. Then delete check.php, because phpinfo() hands your whole server configuration to anyone who guesses the URL. And if check.php throws a 500 as well, your .htaccess is still broken and you haven’t renamed it yet.

On FPM or FastCGI the equivalent file is .user.ini, placed in your WordPress root, containing memory_limit = 256M and nothing else. One documented gotcha comes with it, and it wastes a lot of time. PHP caches these files for 300 seconds by default, set by user_ini.cache_ttl. Save the file, reload immediately, see no change, and it looks like the fix failed. It hasn’t. Wait five minutes.

Two related traps live in the same file. Any rule copied from a tutorial that references a module your server doesn’t load does exactly what php_value does. The usual offender is a SecFilterEngine line, pasted in to switch off a firewall. On NGINX, meanwhile, none of this applies. NGINX has no .htaccess mechanism, so the file sits there ignored and can’t be your cause. LiteSpeed and OpenLiteSpeed do read it, which is why “check .htaccess” stays sound advice on most shared hosting.

Memory Limits: The Real Numbers

The defaults are lower than most people assume, and knowing them saves you from raising a limit that was never the constraint.

WordPress sets WP_MEMORY_LIMIT to 40M on a single site, and 64M on multisite. It lifts the admin side to WP_MAX_MEMORY_LIMIT of 256M for heavier jobs like media handling and core updates. The core documentation adds the qualifier that matters. WordPress checks what PHP has been allocated first, and it can only request within that. If your host caps PHP at 128M, setting 512M in wp-config.php changes nothing.

That asymmetry between 40M and 256M also explains one common symptom directly. A site whose front end loads fine but whose dashboard throws 500 is often a site sitting between the two limits.

To test it, add define( ‘WP_MEMORY_LIMIT’, ‘256M’ ); to wp-config.php and reload. If the error clears, treat that as a diagnosis and not a repair. Something in your stack is using six times the default to render one page. The honest next step is finding out what. Otherwise the next plugin you install pushes you over the new ceiling too.

File Permissions and Who Owns Your Files

Permission errors produce 500s reliably. They turn up most often after a migration or a restored backup, when files arrive owned by the wrong user.

The safe values are 755 for directories, 644 for files. Set wp-config.php to 640 or 600 if your host allows it. And don’t reach for 777 because a tutorial promised it would fix an upload problem.

Whether 777 actually returns a 500 depends on your handler, and most advice on this point is about a decade out of date. suPHP refuses to run anything group-writable or world-writable, and it announces itself in the log with a distinctive string: SoftException in Application.cpp. Apache’s suEXEC applies a similar rule to CGI programs. It checks that the target is “NOT writable by anyone else”, and that the file’s owner matches the user it runs as. PHP-FPM has no such refusal, and cPanel now recommends it in suPHP’s place. So on a current stack, 777 is a security problem rather than the cause of your 500. Search the error log for that SoftException string before you spend an hour on chmod.

Ownership matters as much as the mode. Every file under your web root should belong to your hosting account’s user. Not to root, and not to the web server user. If a permission fix doesn’t take and you’re on shared hosting, open a ticket here. Correcting ownership needs access your account doesn’t have.

PHP Version Jumps

A site that broke overnight with nothing changed on your side was often changed on your host’s side. PHP end-of-life dates drive scheduled upgrades, and a plugin that hasn’t been updated in three years meets syntax that no longer exists.

The dates come straight from php.net’s supported-versions table. PHP 8.1 stopped receiving security fixes on 31 December 2025. PHP 8.2 has been security-only since the end of 2024, with its own cutoff on 31 December 2026. PHP 8.3 gets patches through 2027, 8.4 through 2028, and 8.5, released 20 November 2025, through 2029.

WordPress itself has stayed still while PHP moved. WordPress 7.0 “Armstrong” shipped on 20 May 2026 and 7.1 “Mary Lou” on 19 August 2026, and neither raised the PHP floor above 7.4. The recommendation is still PHP 8.3 or newer. That gap is the trap. WordPress runs happily on a PHP version that stopped getting security fixes years ago. Nothing in your dashboard warns you, right up until a host-side upgrade forces the issue.

If your control panel lets you switch PHP versions, dropping back one minor version is a fast test. It confirms the cause in under a minute. Treat the rollback as temporary, though. You’re now running an older PHP to accommodate code that needs replacing. Our guide to the WordPress “requires a newer PHP version” warning covers how to find which extension is holding you back.

When It’s the Server, Not Your Site

Some 500s aren’t yours to fix, and spotting them early saves you from renaming folders that were never the problem.

A firewall rule misfiring. ModSecurity usually returns 403 when it blocks something. Two cases return 500 instead. A rule that misfires during request processing, or an .htaccess line written to switch the firewall off where that isn’t permitted. The tell is in the server error log, where blocked requests carry a rule ID in square brackets. You can’t tune those rules from a shared account, so this one goes to support with the log line attached.

A PHP process pool that died. More often a 502 than a 500, but worth checking when errors come and go under load rather than on every request. Intermittent failures that correlate with traffic are a resource problem, not a code problem, and no amount of plugin renaming touches them.

Disk quota. A full account leaves PHP unable to write session data, temp files or its own log, and those failures surface as a 500. If the site was fine an hour ago, check your usage figure in the control panel before anything else.

Where your error log actually lives

The WordPress debug log records PHP errors inside WordPress. It does not record .htaccess syntax errors, permission refusals or firewall blocks, because those happen before PHP runs. For those you need the server log, and each panel puts it somewhere different:

  • cPanel: the Errors interface under Metrics. cPanel’s own documentation describes it as showing up to 300 of the most recent entries, newest first. Many configurations also drop an error_log file directly in public_html.
  • Hostinger hPanel: File Manager, then the .logs directory in your account root, holding a file named error_log_ plus your domain. PHP errors only, so server-level failures won’t appear there.
  • SiteGround Site Tools: Statistics, then Error Log for recent server-detected errors, with a php_errorlog file in the site root for PHP-level ones.
  • Cloudways: the logs folder inside your application directory, reachable over SSH or SFTP, with separate Apache, NGINX and PHP files.
  • Plain VPS: /var/log/apache2/error.log on Debian and Ubuntu, /var/log/httpd/error_log on RHEL-family systems, /var/log/nginx/error.log for NGINX.

Two Apache log lines are worth recognizing on sight. “Premature end of script headers” and “End of script output before headers” mean the same thing. The script stopped before returning anything the server could use. That’s a PHP process that died mid-request, which points you back at the PHP side rather than the config side.

Which Fix to Try First

Working through every method above in order is how a fifteen-minute problem becomes an afternoon. What you did last, and what still works, narrows it faster than any checklist.

Something changed, and you know what. Updated a plugin, edited functions.php, pasted a snippet, switched theme. Undo that one thing, and nothing else. If it was an auto-update, check whether the version you’re on still exists on WordPress.org before you debug it. A withdrawn release is not your bug to solve.

Nothing changed, and it broke overnight. This is host-side until proven otherwise. Check your PHP version first, then your disk quota, then the server error log. A scheduled PHP upgrade or a hit resource cap explains most of these, and neither leaves a trace in wp-content/debug.log.

Only /wp-admin throws 500. The front end loads fine, so memory is the first candidate, given core’s own 40M against 256M split. Second is a corrupted file in wp-admin or wp-includes. A clean core reinstall fixes that without touching your content. Replace those two directories from a fresh WordPress download, and leave wp-content and wp-config.php exactly where they are.

A browser and nothing else. No FTP, no SSH, no file manager. Your host’s control panel almost certainly has a file manager, so start there. If it doesn’t, the sequence is: check the inbox for a recovery link, then log a ticket with the exact time of the first failure. Support can read logs you can’t.

It comes and goes. Intermittent 500s under traffic are a capacity problem. Renaming plugin folders will not help, and neither will a memory constant. The limit you’re hitting belongs to the account, not to the request. Either the site needs fewer moving parts or the plan needs more headroom. This is where managed WordPress hosting stops being a luxury, since resource ceilings and PHP upgrades get handled for you rather than announced at you.

Stopping It Coming Back

Most repeat 500s trace to one habit: updating live, all at once, with no way back. Fixing that is cheap.

Update in small batches and reload the site between them. Ten plugins updated together give you ten suspects and no information. Take a backup before anything that touches core or a deeply-integrated plugin. Then confirm you can restore it, because an untested backup is a guess about the future.

Set the admin email to a mailbox someone reads. Recovery mode is worthless if the link lands in an abandoned inbox. Keep PHP on a version that’s still getting security patches. As of September 2026 that technically includes 8.2, but only until 31 December, so 8.3 or newer is the one to be on. Treat a host’s upgrade notice as a testing deadline, not an announcement to file away. And if a plugin sits at the center of your site, check its release history now and then. One that ships a broken package once tends to do it again.

Staging is the real answer, and plenty of shared plans now include it instead of reserving it for the expensive tiers. One click to copy the site, break the copy, and leave the live version alone. If your plan doesn’t have it, that’s worth weighing against price the next time you renew.

Frequently Asked Questions

What causes a 500 internal server error all of a sudden?

Something changed, even if you didn’t change it. On your side, that’s usually a plugin or theme update, an edit to functions.php, or a snippet pasted into wp-config.php. On your host’s side, it’s a PHP version upgrade, a hit resource cap, or a full disk. If you genuinely changed nothing, check your PHP version and your disk usage before you start renaming folders.

Can I fix a 500 internal server error myself, or do I need my host?

Most of them, yes. Renaming .htaccess, renaming the plugins folder, raising the memory limit and fixing file permissions all work over FTP or a file manager. Three cases need your host. File ownership problems, ModSecurity rules firing on your requests, and PHP-FPM pools that keep dying. Each needs access your account doesn’t have. Send support the exact time of the failure, plus the log line if you have one.

Why do I get a 500 error only in wp-admin when the front end works?

Usually memory. WordPress allows 40M by default on the front end, and raises it to 256M for admin tasks. A dashboard that dies while the site loads is often sitting between those two figures, on a plan that can’t reach the higher one. The other common cause is a corrupted file in wp-admin or wp-includes. Fix that by replacing both directories from a fresh WordPress download, leaving wp-content and wp-config.php alone.

Is a 500 error the same as 502, 503 or 504?

No, and the difference tells you who fixes it. A 500 means the application broke, so it’s usually yours. A 502 means a proxy got an invalid response from the backend, typically a dead PHP-FPM process. A 503 means the server is refusing requests deliberately, through overload or a maintenance mode. A 504 means the backend never answered in time. The last three point at infrastructure, so they go to your host with the timestamp attached.

How do I fix a 500 error if I can’t log in to WordPress at all?

You don’t need the dashboard for any of the main fixes. Renaming .htaccess and renaming wp-content/plugins both work over FTP or a hosting file manager. WordPress skips plugins whose folders have disappeared, though you have to load /wp-admin once to make that stick in the database. With SSH, wp plugin deactivate –all plus the –skip-plugins flag boots WordPress without loading plugins, so the fatal never fires. If the crash happens only at the login screen rather than site-wide, the cookie and lockout causes are a separate list.

Does a 500 internal server error hurt my Google rankings?

A short one won’t. Google’s own crawling documentation says 5xx errors make its crawlers “temporarily slow down with crawling”. It also says already-indexed URLs are kept, then “eventually dropped” if the error persists. So hours are fine, and days are not. Fix it the same day and you’ll almost certainly see no ranking effect at all. The real cost during an outage is lost traffic and lost trust, not a lasting penalty afterwards.

How long does it take to fix a 500 error?

If it’s .htaccess or a single plugin, ten minutes, and most of that is waiting for FTP. If it’s a memory ceiling or a PHP version mismatch, an hour or two, since you’re testing rather than just reverting. If it’s ownership, a firewall rule or a dying process pool, it takes as long as your host’s ticket queue. That’s the real argument for identifying which of the three you have before you start.

The Short Version

Look at the page before you look at a checklist. A styled WordPress error means the crash happened inside WordPress, so check the admin inbox for a recovery link and then read wp-content/debug.log. A bare server page means the crash happened before WordPress loaded, so rename .htaccess, then check that directories are 755 and files are 644. A blank page means turning off the fatal error handler for thirty seconds will tell you what PHP actually saw.

Then resist the fix everyone recommends without qualification. Adding php_value memory_limit to .htaccess is a working fix on mod_php and an instant 500 on PHP-FPM, and PHP’s own manual says which is which. If your host runs FPM, the file is .user.ini, and it caches for five minutes before your change does anything.

Landed here from a different symptom? Two neighboring problems have their own guides. “Briefly unavailable for scheduled maintenance” is a stuck update rather than a crash, and it clears itself after ten minutes. A crash that only hits the login screen is a different problem again, with cookie and lockout causes that never touch .htaccess.

Researched and written by:
HowToHosting Editors
HowToHosting.guide provides expertise and insight into the process of creating blogs and websites, finding the right hosting provider, and everything that comes in-between. Read more...

Leave a Comment

Your email address will not be published. Required fields are marked *

This website uses cookies to improve user experience. By using our website you consent to all cookies in accordance with our Privacy Policy.
I Agree
At HowToHosting.Guide, we offer transparent web hosting reviews, ensuring independence from external influences. Our evaluations are unbiased as we apply strict and consistent standards to all reviews.
While we may earn affiliate commissions from some of the companies featured, these commissions do not compromise the integrity of our reviews or influence our rankings.
The affiliate earnings contribute to covering account acquisition, testing expenses, maintenance, and development of our website and internal systems.
Trust howtohosting.guide for reliable hosting insights and sincerity.