https://andrewbaker.ninja/wp-content/themes/twentysixteen/fonts/merriweather-plus-montserrat-plus-inconsolata.css

👁7views
You just Uploaded a new Plugin and your WordPress Site Just Crashed. Now What?

You updated a plugin five minutes ago. Maybe it was a security patch. Maybe you were trying a new caching layer. You clicked “Update Now,” saw the progress bar fill, got the green tick, and moved on with your day. Now the site is down. Not partially down. Not slow. Gone. A blank white page. No error message, no admin panel, no way in. Your visitors see nothing. Your contact forms are dead. If you are running WooCommerce, your checkout just stopped processing orders.

If you are running WordPress 5.2 or later, you might not even get a white screen. Instead you get this:

There has been a critical error on this website. Please check your site admin email inbox for instructions.

That is the exact message. No stack trace, no file name, no line number. Just a single sentence telling you to check an email that may or may not arrive. WordPress also sends a notification to the admin email address with the subject line “Your Site Is Experiencing a Technical Issue” containing a recovery mode link. In theory this is helpful. In practice the email takes minutes to arrive, may land in spam, or may never arrive at all if your site’s mail configuration is itself broken (which it often is on cheap shared hosting).

If you are running WordPress older than 5.2, you get nothing. A blank white page. No message at all. That is the original White Screen of Death.

Either way, the question is not whether it will happen to you. The question is what happens in the 60 seconds after it does.

1. Why WordPress Does Not Protect You

WordPress has no runtime health check. There is no circuit breaker, no post activation validation, no automatic rollback. When you activate a plugin, WordPress writes the plugin name into an active_plugins option in the database and then loads that plugin’s PHP file on the next request. If that file throws a fatal error, PHP dies and takes the entire request pipeline with it. Apache or Nginx returns a 500 or a blank page. WordPress never gets far enough into its own boot sequence to realise something is wrong.

There is a recovery mode that was introduced in WordPress 5.2. It catches fatal errors and sends an email to the admin address with a special recovery link. In theory this is helpful. In practice it has three problems. First, the email may take minutes to arrive or may never arrive at all if your site’s mail configuration is itself broken (which it often is on cheap shared hosting). Second, the recovery link expires after a short window. Third, it only pauses the offending plugin for the recovery session. It does not deactivate it permanently. If you log in via the recovery link but forget to deactivate the plugin manually, the next regular visitor request will crash the site again.

The core issue is architectural. WordPress loads every active plugin on every request. There is no sandbox, no isolation, no health gate between plugin activation and the next page load. A single throw or require of a missing file in any active plugin will take down the entire application. The plugin system is cooperative, not defensive.

2. What Recovery Normally Looks Like

If you have SSH access, the fix takes about 30 seconds. You connect to the server, navigate to wp-content/plugins/, and either rename or delete the offending plugin directory. The next request to WordPress skips the missing plugin and the site comes back.

If you do not have SSH, you try FTP. Most hosting providers still offer it. You open FileZilla or whatever client you have configured, navigate to the plugins folder, and do the same thing. This takes longer because FTP clients are slow, and if you do not have your credentials saved, you are now hunting through old emails from your hosting provider.

If you do not have FTP, or you are on a managed host that restricts file access, you file a support ticket. On a good host this gets resolved in minutes. On a bad one it takes hours. On a weekend it takes longer. Your site is down the entire time.

If you have a backup plugin and it stored snapshots externally (S3, Google Drive, Dropbox), you can restore from the last known good state. This works, but it is a sledgehammer for a thumbtack. You are restoring the entire site, including the database, to fix a single bad plugin file. If any content was created between the backup and the crash, it is gone.

Every one of these options assumes technical knowledge, preconfigured access, or a responsive support team. Most WordPress site owners have none of the three.

The Emergency SSH One (Two) Liner(s)

If you do have SSH access and you just need the site back up immediately, two commands. First, see what you are about to kill:

find /var/www/html/wp-content/plugins -maxdepth 1 -mindepth 1 -type d -mmin -60 -printf '%T+ %f\n' | sort

This lists every plugin folder modified in the last 60 minutes with its timestamp. Review the output. If you are happy with the list, delete them:

find /var/www/html/wp-content/plugins -maxdepth 1 -mindepth 1 -type d -mmin -60 -exec rm -rf {} \;

Adjust the path if your WordPress installation is not at /var/www/html. On many hosts it will be /home/username/public_html or similar. Change -mmin -60 to -mmin -30 for 30 minutes or -mmin -120 for two hours.

This is the nuclear option. It does not deactivate the plugin cleanly through WordPress. It deletes the files from disk. WordPress will notice the plugin is missing on the next request and remove it from the active plugins list automatically. If you need to be more surgical, use WP-CLI instead:

wp plugin deactivate $(find /var/www/html/wp-content/plugins -maxdepth 1 -mindepth 1 -type d -mmin -60 -printf '%f\n') --path=/var/www/html

This deactivates recently modified plugins without deleting them, so you can inspect them later.

3. The Watchdog Pattern

The solution is a plugin that watches the site from the inside. Not a monitoring service that pings your URL from an external server and sends you an alert. Not an uptime checker that tells you the site is down (you already know the site is down). A plugin that detects the crash, identifies the cause, and fixes it automatically before you even notice.

The pattern works like this. A lightweight cron job fires every 60 seconds. Each tick does three things.

Probe. The plugin sends an HTTP GET to a dedicated health endpoint on its own site. The endpoint is registered at init priority 1, before themes and most other plugins load. It returns a plain text response: CLOUDSCALE_OK. No HTML, no template, no database queries. The request includes cache busting parameters and no cache headers to ensure CDNs and browsers do not serve a stale 200 when the site is actually dead.

Evaluate. If the probe comes back HTTP 200 with the expected body, the site is healthy. The tick exits and does nothing. No logging, no database writes, no overhead.

Recover. If the probe fails (500 error, timeout, connection refused, unexpected response body), the plugin scans the wp-content/plugins/ directory and identifies the plugin file with the most recent modification time. If that file was modified within the last 10 minutes, the watchdog deactivates it, deletes its files from disk, and lets the next cron tick re-probe to confirm the site is back.

The entire recovery loop takes less than two minutes from crash to restored site. No human intervention. No SSH. No support ticket.

4. The Recovery Window

The 10 minute window is the most important design decision in the plugin. It defines the boundary between “a plugin that was just installed or updated” and “a plugin that has been sitting on the server for days.”

Without a time window, the watchdog would be dangerous. If the site crashes because the database is down or the disk is full, the watchdog would delete whatever plugin happens to have the newest file, even if that plugin has been stable for months and had nothing to do with the crash. That would be worse than the original problem.

The 10 minute window scopes the blast radius. The watchdog only acts on plugins that were modified in the last 600 seconds. If no plugin was recently modified, the watchdog sees the crash, finds no candidate, and does nothing. This is the correct behaviour. A crash with no recent plugin change is a server problem, not a plugin problem, and the watchdog should not try to fix server problems.

The timing scenarios are worth walking through explicitly.

You install a plugin at 14:00. The site crashes at 14:03. The plugin’s file modification time is 3 minutes ago, well within the window. The watchdog removes it.

You install a plugin at 14:00. The site crashes at 14:15. The plugin’s file modification time is 15 minutes ago, outside the window. The watchdog sees the crash but finds no candidate within the window. It does nothing. This is correct. If the plugin ran fine for 15 minutes and the site only now crashed, the plugin is probably not the cause.

You update two plugins at 14:00 and 14:05. The site crashes at 14:06. The watchdog finds the 14:05 plugin (most recently modified) and removes it. If the site is still down at the next tick 60 seconds later, the 14:00 plugin is now the most recently modified and still within the window. It gets removed next. The watchdog works through the candidates sequentially, most recent first.

5. What It Deletes and What It Leaves Alone

The watchdog targets one plugin per tick: the most recently modified file within the recovery window. It deactivates the plugin first (removes it from the active_plugins list in the database), then deletes the plugin’s files from disk.

It deletes rather than just deactivates. A deactivated plugin still has files on disk that could be autoloaded, could contain vulnerable code, or could conflict with other plugins through file level includes. If the plugin crashed your site, you do not want its files sitting around. You want it gone. You can reinstall it later once you have investigated the issue.

The watchdog never touches itself. It explicitly skips its own plugin file when scanning for candidates. It also never touches themes, mu-plugins, or drop-in plugins. Its scope is strictly the wp-content/plugins/ directory.

It does not act on database corruption. It does not act on PHP version incompatibilities at the server level. It does not act on disk space exhaustion, memory limit errors caused by the WordPress core, or misconfigurations in wp-config.php. It is a single purpose tool with a narrow scope, and that narrowness is what makes it safe.

6. The Design Decisions

Single file, no dependencies. The entire plugin is one PHP file. No Composer packages, no JavaScript assets, no CSS, no database tables, no options. A recovery tool that requires its own infrastructure is a recovery tool that can fail for infrastructure reasons. The fewer moving parts, the more likely it works when everything else is broken.

No configuration UI. There is no settings page. There is nothing to configure. The recovery window is a constant in the code. The probe endpoint is hardcoded. The cron schedule is fixed at 60 seconds. Every configuration option is a potential misconfiguration. A watchdog plugin that requires the user to set it up correctly is a watchdog plugin that will be set up incorrectly on exactly the sites that need it most.

Self probe, not external ping. The plugin probes itself from inside WordPress, not from an external monitoring service. This means it works on localhost development environments, on staging servers behind VPNs, on intranets, and on any host where inbound HTTP is restricted. It also means the probe tests the full WordPress request pipeline, not just whether the server is responding to TCP connections.

SSL verification disabled on the probe. The self probe sets sslverify to false. This is deliberate. Many staging and development environments use self signed certificates. A watchdog that fails because it cannot verify its own SSL certificate is useless in exactly the environments where you are most likely to be testing plugin changes.

Cache busting on every probe. The probe URL includes a timestamp parameter and sends explicit no cache headers. WordPress sites frequently run behind Varnish, Cloudflare, or plugin level page caches. Without cache busting, the probe could receive a cached 200 response from the CDN while the origin server is returning 500 errors. The site would appear healthy when it is actually dead.

7. WordPress Cron: The One Thing You Need to Know

WordPress does not have a real cron system. The built in “WP-Cron” is triggered by visitor requests. When someone visits your site, WordPress checks whether any scheduled events are due and runs them before serving the page.

This means on a low traffic site, the watchdog might not tick for several minutes or even hours if nobody visits. On a crashed site with zero traffic, it might never tick at all, because the crash happens before WordPress gets far enough into its boot sequence to check the cron schedule.

The fix is a real system cron. One line in your server’s crontab:

* * * * * curl -s https://yoursite.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1

This hits wp-cron.php every 60 seconds regardless of visitor traffic. Combined with the watchdog plugin, it means your site self heals within two minutes of a plugin crash, even if nobody is visiting.

If you are on shared hosting without cron access, services like EasyCron or cron-job.org can make the same request externally. Some managed WordPress hosts (Kinsta, WP Engine, Cloudways) already run system cron for you. Check with your host.

8. Test It Yourself

Confidence in a recovery tool comes from seeing it work. Included with this post is a downloadable test plugin: CloudScale Crash Test. It is a WordPress plugin that does exactly one thing: throw a fatal error on every request, immediately white screening your site:

https://andrewninjawordpress.s3.af-south-1.amazonaws.com/cloudscale-plugin-crash-recovery.zip

The test procedure:

  1. Install and activate CloudScale Plugin Crash Recovery on your site
  2. Confirm your system cron is running (or that your site has enough traffic to trigger WP-Cron reliably)
  3. Install and activate the CloudScale Crash Test plugin
  4. Your site will immediately show: “There has been a critical error on this website. Please check your site admin email inbox for instructions.”
  5. Wait 60 to 120 seconds
  6. Refresh your site. It should be back online
  7. Check your plugins list. CloudScale Crash Test should be gone

The crash test plugin contains a single throw new \Error() statement at the top level. It is not subtle. It does not simulate a partial failure or an intermittent bug. It kills the site immediately on every request. If the watchdog can recover from this, it can recover from any plugin that fatal errors within the recovery window.

Do not install the crash test plugin on a production site without the recovery plugin active. If you do and your site is down, SSH in and run:

rm -rf /var/www/html/wp-content/plugins/cloudscale-crash-test-plugin/

Adjust the path to match your WordPress installation. On most shared hosts this will be /home/username/public_html/wp-content/plugins/cloudscale-crash-test-plugin/. Your site will come back on the next request.

9. When This Does Not Help

No tool solves every problem, and it is worth being explicit about the boundaries.

The watchdog does not help if the crash is caused by a theme. Themes are loaded through a different mechanism and the watchdog only scans the plugins directory. It does not help if the crash is caused by a mu-plugin (must use plugin), because mu-plugins load before regular plugins and before the cron system has a chance to act. It does not help if the database is down, because WordPress cannot read its own options (including the active plugins list) without a database connection. It does not help if the server’s PHP process is completely dead, because there is no PHP runtime to execute the cron tick.

It also does not help if the crash happens more than 10 minutes after the plugin was installed. If you install a plugin at 09:00 and it causes a crash at 11:00 due to a cron job or a deferred activation hook, the plugin’s file modification time is two hours old and outside the recovery window. The watchdog will see the crash but find no candidate to remove. This is a design tradeoff: a wider window catches more edge cases but increases the risk of removing an innocent plugin.

The watchdog is one layer in a broader defence strategy. It handles the most common failure mode (a recently installed or updated plugin that immediately crashes the site) and handles it automatically. For everything else, you still need backups, monitoring, and access to your server.

10. The Code

The full source code is available on GitHub under GPLv2. It is a single PHP file with no dependencies:

CloudScale Plugin Crash Recovery on GitHub

The crash test plugin is available as a zip download attached to this post.

Install the recovery plugin. Set up your system cron. Forget about it until it saves you at 2am on a Saturday when a plugin auto update goes wrong and you are nowhere near a terminal. That is the point.

Leave a Reply

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