DEV Community

WP Multitool
WP Multitool

Posted on • Edited on • Originally published at wpmultitool.com

WordPress Site Down? The Emergency Recovery Guide (2026)

It's 11 PM. Your phone buzzes. Client email: "The site is down."

You open the URL. White screen. Nothing. No error message, no clue, just a blank page staring back at you like it forgot everything it ever was.

I've been there more times than I'd like to admit. After 15+ years of building and maintaining WordPress sites, I can tell you this: 90% of WordPress crashes come from the same 6 or 7 causes. And most of them are fixable in under 20 minutes - if you know where to look.

This is the guide I wish I'd had the first time a production site went dark on me. Not a vague checklist. A systematic, step-by-step emergency recovery plan. Bookmark it. You'll need it eventually.

The First 60 Seconds: Triage

Before you touch anything on the server, spend one minute ruling out false alarms. I've wasted hours debugging a "crashed" site that was actually a DNS propagation issue.

Check these four things first:

# 1. Is the site actually returning an error, or is it your connection?
curl -I https://yoursite.com

# 2. What HTTP status code are you getting?
curl -s -o /dev/null -w "%{http_code}" https://yoursite.com

# 3. Is DNS resolving correctly?
dig yoursite.com +short

# 4. Can you reach the server at all?
ping -c 3 yoursite.com
Enter fullscreen mode Exit fullscreen mode

The HTTP status code tells you almost everything you need to know about where to look:

Status Code What It Means Where to Look
200 Server is fine, content is broken Theme, frontend, cache
301/302 loop Redirect misconfiguration wp-config.php, .htaccess
403 Permission denied File permissions, .htaccess, security plugin
500 Server-side PHP crash Error logs, plugins, memory
502 PHP process died PHP-FPM, memory, timeout
503 Server overloaded or maintenance mode .maintenance file, server load
521/522 Cloudflare can't reach origin Server is actually down

Also try loading the site on your phone's mobile data (rules out local DNS cache) and check your host's status page - if their whole infrastructure is down, there's nothing to debug on your end.

If curl returns a 200 but the page looks broken, that's a frontend/caching issue. If you're getting 500, 502, or 503, keep reading.

Terminal showing curl commands with different HTTP status codes and their meanings

Enable WordPress Debug Mode (Do This First)

Before you start changing things, turn on error logging. Flying blind is the number one reason people spend 3 hours on a fix that should take 10 minutes.

SSH into your server and edit wp-config.php. Add these lines before the /* That's all, stop editing! */ comment:

// Add this BEFORE "That's all, stop editing!"
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);
Enter fullscreen mode Exit fullscreen mode

WP_DEBUG turns on error reporting, WP_DEBUG_LOG writes them to wp-content/debug.log, and WP_DEBUG_DISPLAY keeps them hidden from visitors. Now reload and check the log:

tail -100 /var/www/yoursite/wp-content/debug.log
Enter fullscreen mode Exit fullscreen mode

Nine times out of ten, the answer is right there. A fatal error with a file path and line number pointing directly to the broken plugin or theme.

Important: Remove these debug lines once you've fixed the issue. A debug.log file left running on production can grow to gigabytes and will leak internal paths if someone guesses the URL.

The White Screen of Death (WSOD)

The WSOD is WordPress's most dramatic failure mode. No error message, no clue - just white nothing. It happens when PHP hits a fatal error and has nothing left to display.

What causes it:

  • A plugin update introduced a PHP fatal error
  • Theme code referencing a function that no longer exists
  • PHP memory exhaustion (script ran out of RAM mid-execution)
  • A syntax error in wp-config.php or functions.php

The fix sequence:

Step 1: Check the error log

# WordPress debug log
tail -50 wp-content/debug.log

# Server error logs (location varies by host)
tail -50 /var/log/apache2/error.log
tail -50 /var/log/nginx/error.log

# Some hosts put it here
tail -50 ~/logs/error.log
Enter fullscreen mode Exit fullscreen mode

If you see something like PHP Fatal error: Allowed memory size of 67108864 bytes exhausted, jump to the memory section below. If you see Cannot redeclare function or Call to undefined function, it's a plugin conflict - jump to the plugin isolation section.

Step 2: Increase PHP memory (temporary band-aid)

// In wp-config.php
define('WP_MEMORY_LIMIT', '256M');
define('WP_MAX_MEMORY_LIMIT', '512M');
Enter fullscreen mode Exit fullscreen mode

If the WSOD disappears after this, the site was running out of memory. But don't stop here - the memory increase is a band-aid. Something is consuming unreasonable amounts of RAM, and you need to find out what. More on that in the memory section.

Step 3: Disable all plugins via filesystem

If the log doesn't give you a clear answer, do the plugin isolation test (covered in detail below).

Step 4: Switch to a default theme

If plugins aren't the culprit:

# Via WP-CLI
wp theme activate twentytwentyfour

# Or via filesystem - rename your active theme folder
mv wp-content/themes/your-theme wp-content/themes/your-theme-disabled
Enter fullscreen mode Exit fullscreen mode

WordPress will fall back to a default theme. If the site loads, your theme has a fatal error.

Annotated debug.log file showing a PHP Fatal error with the plugin file path highlighted

500 Internal Server Error

The 500 error is the server saying "something went wrong but I'm not going to tell you what." Helpful, right?

Most common causes in WordPress:

Corrupted .htaccess

This is cause #1 for 500 errors on Apache servers. A failed permalink save, a misbehaving security plugin, or a botched redirect rule can corrupt .htaccess silently.

# Rename .htaccess to take it out of play
mv .htaccess .htaccess.broken

# Create a minimal clean one
cat > .htaccess << 'EOF'
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
EOF
Enter fullscreen mode Exit fullscreen mode

Reload. If the site works, the old .htaccess had a bad rule. You can regenerate a clean one from Settings > Permalinks in wp-admin (just click Save - it rewrites the file).

PHP version mismatch

Your host upgraded PHP and a plugin doesn't support the new version. Check which PHP version is running:

php -v
# Or for the web server's PHP (might differ from CLI):
wp eval 'echo phpversion();'
Enter fullscreen mode Exit fullscreen mode

If you recently saw your host announce a PHP 8.x upgrade, that's likely your answer. Some older plugins still use create_function(), each(), or other removed features. The error log will tell you exactly which function and which file.

File permission issues

# Fix standard WordPress permissions
find /var/www/yoursite -type d -exec chmod 755 {} \;
find /var/www/yoursite -type f -exec chmod 644 {} \;
chmod 600 wp-config.php
Enter fullscreen mode Exit fullscreen mode

Wrong permissions - especially files set to 777 or directories with no execute bit - will trigger 500 errors on most Apache/Nginx configs.

Error Establishing a Database Connection

This one is scary because it looks like your data might be gone. It almost never is. The most common causes are boring and fixable:

1. Check if MySQL is actually running

# Check MySQL/MariaDB status
systemctl status mysql
# or
systemctl status mariadb

# If it's down, start it
sudo systemctl start mysql
Enter fullscreen mode Exit fullscreen mode

MySQL crashes more often than people think, especially on shared hosting or small VPS instances where RAM is tight. If MySQL keeps crashing, check dmesg or /var/log/syslog for OOM (out-of-memory) killer entries.

2. Verify wp-config.php credentials

// These four lines in wp-config.php must match your actual database
define('DB_NAME', 'your_database');
define('DB_USER', 'your_db_user');
define('DB_PASSWORD', 'your_db_password');
define('DB_HOST', 'localhost');  // Sometimes '127.0.0.1' or a socket path
Enter fullscreen mode Exit fullscreen mode

Test them manually:

mysql -u your_db_user -p'your_db_password' your_database -e "SELECT 1;"
Enter fullscreen mode Exit fullscreen mode

If that fails, the credentials are wrong. Did someone change the DB password? Did you migrate from another host and forget to update DB_HOST?

3. Check disk space

df -h
Enter fullscreen mode Exit fullscreen mode

If the disk is 100% full, MySQL can't write to its temporary files and will refuse connections. Common culprit: unrotated logs filling up the partition. Clear space and restart MySQL.

4. Repair the database

If MySQL is running and credentials are correct, the tables themselves might be corrupted (usually from a server crash during a write operation):

// Add to wp-config.php temporarily
define('WP_ALLOW_REPAIR', true);
Enter fullscreen mode Exit fullscreen mode

Then visit yoursite.com/wp-admin/maint/repair.php in your browser. Click "Repair and Optimize Database."

Remove that line from wp-config.php immediately after. It requires no authentication, so leaving it in means anyone can trigger a database repair on your site.

Or do it from the command line:

wp db repair
wp db optimize
Enter fullscreen mode Exit fullscreen mode

5. Check for slow queries choking the database

Sometimes the database connection isn't truly lost - it's just so overloaded with slow queries that new connections time out. If the error is intermittent (works sometimes, fails other times), this is likely the cause. Run SHOW PROCESSLIST; in MySQL to see what's running.

Diagram showing WordPress to MySQL connection flow and common failure points

PHP Fatal Error: Memory Exhausted

The full error looks something like:

PHP Fatal error: Allowed memory size of 134217728 bytes exhausted
(tried to allocate 65536 bytes) in /var/www/site/wp-content/plugins/
some-plugin/includes/class-heavy.php on line 247
Enter fullscreen mode Exit fullscreen mode

The error tells you exactly which plugin and which file is consuming the memory. That's your starting point.

Quick fix: Raise the limit

// wp-config.php
define('WP_MEMORY_LIMIT', '256M');
define('WP_MAX_MEMORY_LIMIT', '512M');
Enter fullscreen mode Exit fullscreen mode

You can also set it in php.ini or .htaccess:

# php.ini
memory_limit = 256M
Enter fullscreen mode Exit fullscreen mode
# .htaccess (Apache only)
php_value memory_limit 256M
Enter fullscreen mode Exit fullscreen mode

Real fix: Find the memory hog

Raising the limit buys you time. But if a single plugin is eating 256MB of RAM on every page load, you have a performance problem that will bite you again.

The error message names the file. Look at it:

  • Is it a page builder doing something ridiculous during rendering?
  • Is it a WooCommerce query loading every product into memory?
  • Is it a backup plugin trying to zip the entire site in PHP memory?

Common offenders: bloated page builders, import/export plugins, and analytics plugins that dump everything into wp_options as autoloaded data. Use WP Multitool's backend performance scanner to identify resource hogs before things reach the crash stage.

How to Identify the Culprit Plugin

Plugin conflicts are the single most common cause of WordPress crashes. Here's the systematic way to find the guilty one.

Method 1: Filesystem rename (no wp-admin needed)

This is the method you use when you can't access wp-admin at all:

cd /var/www/yoursite/wp-content

# Disable ALL plugins at once by renaming the folder
mv plugins plugins_disabled

# Create an empty plugins folder so WordPress doesn't error
mkdir plugins
Enter fullscreen mode Exit fullscreen mode

Reload the site. If it works, a plugin was the cause. Now bring them back one at a time:

# Remove the empty folder
rmdir plugins

# Restore the original
mv plugins_disabled plugins

# Now disable all plugins from the database level
wp plugin deactivate --all

# Reactivate one at a time, testing the site after each
wp plugin activate akismet
# test...
wp plugin activate woocommerce
# test...
wp plugin activate contact-form-7
# test... crash! Contact Form 7 is the culprit (just an example)
Enter fullscreen mode Exit fullscreen mode

Method 2: WP-CLI (faster if it's available)

# Deactivate everything
wp plugin deactivate --all

# List all plugins so you can reactivate systematically
wp plugin list --status=inactive --format=table

# Activate one by one
wp plugin activate plugin-slug
Enter fullscreen mode Exit fullscreen mode

Method 3: Binary search (for sites with 30+ plugins)

If you have a lot of plugins, testing one at a time is slow. Use binary search instead:

# Get all inactive plugins (after deactivating all)
wp plugin list --status=inactive --field=name > /tmp/all-plugins.txt

# Count them
wc -l /tmp/all-plugins.txt

# Activate the first half
head -n 15 /tmp/all-plugins.txt | xargs -I {} wp plugin activate {}
# Test the site...

# If it works, the culprit is in the second half
# If it crashes, the culprit is in the first half
# Split that half again and repeat
Enter fullscreen mode Exit fullscreen mode

This finds the problem plugin in log2(n) steps instead of n. For 30 plugins, that's 5 tests instead of 30.

Pro tip: After finding the culprit, check if there's an update (wp plugin update plugin-slug). The crash might be a known bug that's already fixed. If the plugin is abandoned (no updates in 12+ months), find a replacement.

Flowchart showing binary search plugin isolation - disable all then activate half and test

WP-CLI Recovery Commands (When wp-admin Is Gone)

WP-CLI is your lifeline when the admin dashboard is unreachable. If you don't have it installed, you should - it's the single most useful tool for WordPress emergencies. Check our WP-CLI commands reference for the full list.

Here are the commands I reach for during emergencies:

Core recovery

# Verify WordPress core files haven't been modified or corrupted
wp core verify-checksums

# If files are corrupted, re-download core without touching wp-content
wp core download --force --skip-content

# Check what version you're running
wp core version

# Update core if needed
wp core update
Enter fullscreen mode Exit fullscreen mode

Plugin management

# List all plugins with their status and version
wp plugin list --format=table

# Deactivate a specific plugin you suspect
wp plugin deactivate suspicious-plugin

# Deactivate everything
wp plugin deactivate --all

# Check for available updates
wp plugin list --update=available --format=table

# Update a specific plugin
wp plugin update plugin-slug
Enter fullscreen mode Exit fullscreen mode

Theme management

# Switch to a default theme
wp theme activate twentytwentyfour

# List installed themes
wp theme list --format=table

# Switch to a default theme to rule out theme issues
wp theme activate twentytwentyfour
Enter fullscreen mode Exit fullscreen mode

Database operations

# Test database connectivity
wp db check

# Repair corrupted tables
wp db repair

# Optimize tables (reclaim space, fix fragmentation)
wp db optimize

# Search and replace (useful after migration)
wp search-replace 'old-domain.com' 'new-domain.com' --dry-run
wp search-replace 'old-domain.com' 'new-domain.com'

# Export a backup before making changes
wp db export backup-$(date +%Y%m%d).sql
Enter fullscreen mode Exit fullscreen mode

Fix URL and redirect issues

# Check current site URL settings
wp option get siteurl
wp option get home

# Fix wrong URLs (common after migration)
wp option update siteurl 'https://yoursite.com'
wp option update home 'https://yoursite.com'
Enter fullscreen mode Exit fullscreen mode

Clear everything

# Flush object cache
wp cache flush

# Flush rewrite rules (regenerates .htaccess / permalink structure)
wp rewrite flush

# Delete all transients (cached temporary data)
wp transient delete --all
Enter fullscreen mode Exit fullscreen mode

The "Stuck in Maintenance Mode" fix

If a WordPress update was interrupted, you'll see "Briefly unavailable for scheduled maintenance. Check back in a minute." That message comes from a .maintenance file in the WordPress root:

# Just delete it
rm /var/www/yoursite/.maintenance
Enter fullscreen mode Exit fullscreen mode

Done. Site's back.

Reading PHP Error Logs (A Quick Primer)

Error logs are intimidating if you've never read one. But the format is actually simple. Here's a real example:

[23-Mar-2026 22:14:07 UTC] PHP Fatal error: Uncaught Error: Call to
undefined function some_old_function() in /var/www/yoursite/wp-content/
plugins/broken-plugin/includes/class-main.php on line 142
Enter fullscreen mode Exit fullscreen mode

Breaking it down:

Part What It Tells You
[23-Mar-2026 22:14:07 UTC] When the error happened
PHP Fatal error Severity - Fatal means the site crashed
Call to undefined function The type of error
some_old_function() The specific function that's missing
/wp-content/plugins/broken-plugin/... Which plugin caused it
on line 142 Exact line in the code

Error severity levels: Fatal error = site is dead, must fix. Parse error = syntax mistake (missing semicolon, unclosed bracket). Warning = something is wrong but the site still works. Notice/Deprecated = minor issues, won't crash the site but worth noting.

Where to find the logs:

# WordPress debug log (if WP_DEBUG_LOG is enabled)
wp-content/debug.log

# Apache
/var/log/apache2/error.log

# Nginx
/var/log/nginx/error.log

# PHP-FPM
/var/log/php-fpm/error.log
# or
/var/log/php8.x-fpm.log

# Shared hosting (cPanel)
~/logs/error.log
# or check cPanel > Error Log in the browser
Enter fullscreen mode Exit fullscreen mode

Useful log reading commands:

# Last 50 errors
tail -50 /path/to/error.log

# Follow the log in real-time (useful while reproducing the error)
tail -f /path/to/error.log

# Search for fatal errors only
grep "Fatal error" /path/to/error.log

# Errors from today only
grep "$(date +'%d-%b-%Y')" /path/to/error.log

# Count errors by type
grep -c "Fatal error" /path/to/error.log
grep -c "Warning" /path/to/error.log
Enter fullscreen mode Exit fullscreen mode

Restore From Backup vs. Fix Forward

This is a decision you'll face every time a site goes down: do you roll back to a known-good backup, or do you diagnose and fix the problem in place?

Here's my decision framework after years of doing this:

Restore from backup when:

  • You know exactly what changed and it was a single action (plugin update, core update, theme change). Rolling back undoes the one thing that broke.
  • The site is hacked. Malware injection means you can't trust any file on the server. Restore from a pre-hack backup, then patch the vulnerability.
  • Time pressure is extreme. Client presentation in 30 minutes? Restore, get the site up, debug later.
  • You don't have SSH access and can't effectively debug from a file manager.

Fix forward when:

  • You can identify the exact error from the logs. If it's a single plugin crash, deactivating that plugin is faster than restoring a full backup.
  • The backup is old. If your last backup is from 3 days ago and there have been orders, content changes, or user registrations since then, restoring means losing that data.
  • It's a configuration issue (wrong URLs, bad .htaccess, permission problem). These are 30-second fixes. No need to restore.
  • The problem is resource-related (memory, disk space, database overload). A backup won't help because the underlying constraint hasn't changed.

How to restore properly

# Always export the current (broken) database first - you might need data from it
wp db export broken-state-$(date +%Y%m%d-%H%M).sql

# Restore from your backup
wp db import backup-file.sql

# Flush caches
wp cache flush
wp rewrite flush
Enter fullscreen mode Exit fullscreen mode

The hybrid approach: Sometimes the smartest move is to restore the database but keep the current files, or vice versa. Plugin update crashed the site? Restore just the files and keep the current database (newer content). Database migration went wrong? Restore the database but keep current plugin versions.

Decision tree for site down - branches to fix forward if you know what changed or restore from backup

Quick Recovery Reference Table

When you're in the middle of an emergency, you don't want to read paragraphs. Here's the cheat sheet:

Symptom Most Likely Cause Quick Fix
White screen (WSOD) Plugin PHP fatal error wp plugin deactivate --all
500 Internal Server Error Corrupted .htaccess or memory Rename .htaccess, check error log
"Error establishing database connection" MySQL down or wrong credentials systemctl status mysql, check wp-config.php
"Briefly unavailable for maintenance" Interrupted WordPress update rm .maintenance
Redirect loop Wrong siteurl/home in database wp option update siteurl 'https://...'
Login redirect loop Cookie or HTTPS mismatch Clear cookies, check FORCE_SSL_ADMIN
"Maximum execution time exceeded" PHP script timeout Increase max_execution_time in php.ini
"Upload: failed to write to disk" Disk full or permission issue df -h and check wp-content permissions
Site loads but looks broken (no CSS) Mixed content or wrong URLs Check for HTTP/HTTPS mismatch
"Your PHP installation appears to be missing the MySQL extension" Missing PHP module after upgrade sudo apt install php8.x-mysql && sudo systemctl restart php8.x-fpm

Prevention: Stop the Next Crash Before It Happens

Recovering from a crash is a skill. Not needing to is better.

Set up monitoring

You need to know the site is down before your client does. At minimum:

  • Uptime monitoring - UptimeRobot (free tier monitors every 5 minutes), Pingdom, or similar. Get an alert within minutes of downtime.
  • Error rate monitoring - Watch the error log for spikes. A sudden flood of warnings often precedes a fatal crash.
  • Resource monitoring - Track PHP memory usage, MySQL connections, and disk space. Problems here are predictable - they build up over time.

Use WP Multitool's scan module to audit plugin health, autoload bloat, and backend performance issues before they become emergencies.

Use a staging site

Never update plugins directly on production. I know it's tempting - "it's just a minor update, what could go wrong?" Everything. Everything could go wrong.

The workflow: clone production to staging, run updates there, test for 24 hours (or at least click through critical pages), then push to production. Yes, it takes more time. No, you won't regret it at 11 PM on a Friday.

Update strategy that doesn't break things

  • WordPress core: Update within a week of release. Minor versions (6.5.1 to 6.5.2) are almost always safe to apply immediately.
  • Plugins: Update on staging first. Read the changelog. "Major refactor" or "breaking changes" means test carefully.
  • PHP version: The big one. PHP major version upgrades (8.0 to 8.1, etc.) can break plugins using deprecated functions. Staging first, always.
  • Don't update everything at once. Update 5 plugins simultaneously and crash? You won't know which one caused it.

Automate backups (and test them)

Daily backups. Off-server. Tested quarterly. "Tested" means you've actually restored one to a staging environment and verified the site works. An untested backup is not a backup - it's a hope.

Reduce your attack surface

Every plugin is a potential failure point. Fewer plugins means fewer things that can crash, conflict, and require updating. Run an audit - for each plugin, ask: is this still needed? Is it maintained? Is there a lighter alternative?

The Emergency Checklist

Print this. Tape it to your monitor. You'll use it.

  1. Verify the site is actually down - curl, different device, different network
  2. Check the HTTP status code - it tells you where to look
  3. Enable WP_DEBUG_LOG - don't debug blind
  4. Read the error log - the answer is usually right there
  5. Disable all plugins - if the log doesn't give a clear answer
  6. Switch to default theme - if disabling plugins didn't help
  7. Check wp-config.php - for syntax errors and wrong credentials
  8. Check .htaccess - rename it and test
  9. Check disk space and MySQL - df -h and systemctl status mysql
  10. Restore from backup - if all else fails and you need the site up NOW

Most WordPress crashes look scary but have boring causes. A typo in wp-config.php. A plugin that doesn't support the new PHP version. MySQL running out of memory on a $5 VPS. The fix is usually straightforward once you know where to look.

The hard part isn't fixing it. The hard part is staying calm enough to be systematic about it.

If you'd rather not deal with this yourself - if the site is down, it's 2 AM, and you have a demo tomorrow - the done-for-you service exists for exactly that. Send the URL, get a diagnosis and fix within an hour, $100 flat. No subscription, no retainer, money held in escrow until you verify it works.

But for the other 95% of situations? This guide will get you there. Systematically, calmly, one step at a time.

Top comments (0)