Skip to content

Plugin health

Arkazzae edited this page Oct 7, 2026 · 1 revision

Plugin health checks the installed plugins for problems that WordPress does not show: plugins closed on WordPress.org, plugins with no update for two years, plugins whose update source is unclear, one-time tools left active, inactive leftovers, and plugins a SafeHouse module can replace. The report is on the SafeHouse settings page and in Tools → Site Health.

WordPress shows a plugin that WordPress.org has closed as up to date, because no update will ever come. That is how abandoned plugins, and plugins sold to someone who added a backdoor, stay installed for years. Known vulnerabilities are a separate job: see Vulnerability alerts.

Module ID plugin_health
Default On
Available Always
WP-CLI wp shouse plugin-health (only while the module runs)
Since 0.1.0

How it works

When it checks

Once a day, on WP-Cron, Plugin health decides whether to check again. It checks when:

  • the list of installed plugins or their versions changed since the last check, or
  • the last check is more than a week old.

A plugin you add, remove or update is therefore picked up within a day. Check now and wp shouse plugin-health --refresh check at once.

Between checks, the report follows the site live in two ways: a plugin deleted since the last check disappears from it, and active or inactive is always the current state.

What it sends to WordPress.org

Each check asks the WordPress.org plugin directory (api.wordpress.org) about the installed plugins, in requests of up to 50 plugins. It sends only their slugs, the short names WordPress.org knows them by. The slug is the one WordPress's own update check found for the plugin, otherwise the plugin's folder name, otherwise its file name without .php. The requests use WordPress's HTTP API, whose default user agent includes the site address.

Plugins with an Update URI header that points somewhere other than w.org or wordpress.org are not sent. They have their own update channel. SafeHouse itself is never checked.

Findings

Finding Severity When it appears Text
Closed critical WordPress.org reports the plugin as closed. "Closed on WordPress.org (DATE, reason: REASON). It gets no more updates; replace or remove it." DATE and REASON come from WordPress.org (a reason looks like security-issue); ? when WordPress.org gives none.
No update warning The plugin's last update on WordPress.org is more than two years old. "No update since 2023-05-14. Probably abandoned."
Not on WordPress.org info WordPress.org does not know the slug (it answers with any error other than closed). "Not on WordPress.org and no update source declared. Make sure you know where its updates come from."
Vendor updates info The plugin has an Update URI header that does not point to w.org or wordpress.org. Such plugins get no closed or no-update check. "Updates come from its vendor, not WordPress.org. Keep the licence active so security fixes arrive."
One-time tool warning The plugin is on the one-time tools list and is active. "One-time tool (migration, search-replace, import, file access or debugging) left active. Delete it when the job is done."
Replaceable info A SafeHouse module does the plugin's job. Shown whether or not that module is on, and for inactive plugins too. "SafeHouse can do this: module "Login limits". Switch it on, then remove this plugin." (with the name of the module)
Inactive info The plugin is inactive. Every inactive plugin gets this line. "Inactive. Inactive plugins can still be attacked through their files; delete it if you do not need it."

A plugin can have several findings, for example closed, replaceable and inactive. Only one of closed, no update and not on WordPress.org applies at a time. Plugins with the most serious findings are listed first.

One-time tools

These plugins are meant for a single job: a migration, a search-replace, an import, file access or debugging. Plugin health warns when one of them is still active:

all-in-one-wp-migration, duplicator, duplicator-pro, migrate-guru, wp-migrate-db, wp-migrate-db-pro, better-search-replace, search-and-replace, velvet-blues-update-urls, go-live-update-urls, wordpress-importer, wp-file-manager, file-manager-advanced, filester, wp-reset, wp-dbmanager, string-locator, loco-translate, query-monitor, debug-bar

An inactive one-time tool gets only the inactive finding.

Where the report appears

  • SafeHouse → Modules → Plugin health → Details: "Last check:" with the date and time, then a table with the columns Plugin and Findings. Inactive plugins carry an inactive badge, and each finding a critical, warning or info badge. With nothing to show, it says "Nothing to report."
  • Tools → Site Health, the test "SafeHouse plugin health": critical when any finding is critical, recommended when any is a warning, good otherwise. The label is "Some plugins need attention" or "No closed, abandoned or forgotten plugins found", the description counts the findings ("1 critical, 2 warnings. Details are on the SafeHouse settings page."), and Open SafeHouse links to the report. Info findings do not change the status.
  • WP-CLI: wp shouse plugin-health.

Plugin health sends no e-mails and writes nothing to the activity log.

Settings

Plugin health has no settings. While it runs, Details shows the report and the Check now button. Before the first check it says "Not checked yet. Use "Check now" or wait for the daily run."

Check now

  1. Go to SafeHouse → Modules → Plugin health and select Details.

  2. Select Check now.

    SafeHouse shows "Plugin health updated." or, when WordPress.org cannot be reached, "Could not reach WordPress.org:" followed by the reason.

When a check cannot reach WordPress.org, SafeHouse keeps the earlier report, and Details adds "The last refresh failed:" with the reason. If there is no earlier report, it stores one without the findings that need WordPress.org (closed, no update, not on WordPress.org). Select Check now again later.

Read the report with WP-CLI

Show the report:

wp shouse plugin-health

The first run on a site that was never checked asks WordPress.org first. To check again before showing the report:

wp shouse plugin-health --refresh

The output has one row per finding, with the columns plugin (the plugin file, such as akismet/akismet.php), severity and finding. Add --format=json, csv or yaml for other formats. When WordPress.org cannot be reached, the command prints Warning: WordPress.org: followed by the reason.

Replace a plugin with a SafeHouse module

The replaceable finding names the SafeHouse module that does the plugin's job. The modules it can name are Header and footer scripts, Duplicate posts and pages, Tweaks, SMTP mail, Maintenance mode, Hardening, Bot protection, Login limits, Cloudflare cache and Omnibus price history. For the full list of plugins, what each module leaves out, and the steps to switch, see Replacing other plugins.

What it stores

  • Option shouse_plugin_health (not autoloaded): the time of the last check, a fingerprint of the installed plugins and versions, the last error, and for each plugin its name, version and findings.

Limitations

  • Findings cannot be dismissed. There is no allowlist and no setting to hide one. A finding goes away only when you deal with the plugin, or when you switch the module off.
  • Every inactive plugin is listed, including ones you keep inactive on purpose.
  • Only plugins are checked, not themes.
  • Plugin health sends no e-mails. Look at Details or Site Health.
  • Plugins are matched to WordPress.org by slug. A plugin that is not from WordPress.org but has the same folder name as a WordPress.org plugin is judged by that plugin's record. An Update URI header in such a plugin keeps it out of the WordPress.org check.
  • The replaceable finding stays while the other plugin is installed, even after you switch the SafeHouse module on.
  • A plugin added since the last check is not in the report until the next check, up to a day later. The checks depend on WP-Cron.
  • Plugin health does not look for known vulnerabilities. Vulnerability alerts does that.

Related pages

Clone this wiki locally