4.1 The notification model

WordPress separates in-admin feedback from email. Manual updates surface in skins or AJAX; background updates can email the site administrator.

How it works

Logged-in users see notices, menu badges, and the Updates screen driven by transients and capabilities. WP_Automatic_Updater sends email for background outcomes through dedicated methods. Manual WP-CLI output is terminal-only unless hooks add behavior. Disabling the automatic updater also suppresses its notification emails per core documentation.

Process flow

  1. Discovery updates transients.
  2. The admin interface reads transients and displays update information.
  3. If background updates run, email may send after completion.
  4. The automatic_updates_complete action runs only when WP_Automatic_Updater::run() records at least one result in its internal $update_results array. If the batch produces no tracked attempts, the hook does not fire (§4.7).

Reference

PathChannel
Manual adminSkin or AJAX JSON
BackgroundEmail and optional hooks
WP-CLIStandard output

Developer resources


4.2 In-admin notices and menu badges

In-admin messaging uses hooks and helpers without wp_mail() for routine update availability notifications.

How it works

update_nag() in wp-admin/includes/update.php hooks to admin_notices and network_admin_notices at priority 3. It outputs a warning admin notice (through wp_admin_notice() with type warning and classes such as update-nag) when a core upgrade is available from get_preferred_from_update_core() with response === 'upgrade'. It skips on update-core.php. Users without the update_core capability may see text directing them to notify the site administrator.

The admin menu update count bubble uses wp_get_update_data() from wp-admin/menu.php. The At a Glance widget uses update_right_now_message() for an update button when appropriate.

Process flow

  1. The admin page renders.
  2. Transients supply update counts.
  3. Capabilities gate which messages appear.
  4. No email sends through these mechanisms alone.

Reference

MechanismPurpose
update_nag()Core upgrade notice
Menu bubbleAggregate update counts
At a Glance widgetQuick action button when the user has capabilities

Developer resources


4.3 Site Health: update-related diagnostic tests

Site Health surfaces configuration risks. It does not block updates.

How it works

WP_Site_Health runs diagnostic tests. Background update tests reflect factors similar to WP_Automatic_Updater::is_disabled(): constants, filters, VCS detection, and related flags. Loopback tests verify that the server can send an HTTP request to itself (relevant for editors and the WordPress 6.6+ fatal detection feature). WordPress 6.3+ adds backup-folder-writable and disk-space checks tied to manual rollback temporary backups. Results are visibility only — confirm behavior in updater code when debugging.

Process flow

  1. The Site Health page loads tests.
  2. Each test returns status and messages.
  3. Administrators use the results to fix environment issues.

Reference

ConcernRelevance
Background updatesMirrors disable conditions
LoopbackAsync features and rollback
Backup folder and disk spaceManual rollback space

Developer resources


4.4 Core background update emails

Core automatic updates email the site administrator for success, failure, critical failure, and sometimes a manual-update prompt when the automatic apply was skipped.

How it works

WP_Automatic_Updater implements paths such as after_core_update() and send_core_update_notification_email(). Types include success, fail, critical, and manual notification (when gated by the API notify_email flag and filters). Site options auto_core_update_notified and auto_core_update_failed deduplicate or schedule retries.

The filter send_core_update_notification_email controls whether to send the “new core version available” mail (the manual prompt). The filter auto_core_update_send_email applies to types success, fail, and critical only — it does not run for manual mails because send_email() skips that gate when $type === 'manual'. The filter auto_core_update_email alters the composed message for sends that use send_email().

The recipient is typically get_site_option( 'admin_email' ) with possible locale switching.

Process flow

  1. A background core update completes or fails.
  2. Core chooses the email type.
  3. Relevant filters run.
  4. wp_mail() sends the email unless a filter disables it.
  5. Persistence options prevent duplicate emails for the same release.

Reference

HookTypeParametersNotes
send_core_update_notification_emailfilterboolWhether to send the manual-update-available mail (notify_email path)
auto_core_update_send_emailfilterbool, stringGates success, fail, and critical background mails — not manual
auto_core_update_emailfilterarrayAlters to, subject, body, and headers for send_email()

Developer resources


4.5 Plugin and theme background update emails

Plugin and theme automatic batches can email summaries with success, failure, or mixed outcomes.

How it works

After plugin or theme auto-updates, after_plugin_theme_update() may call send_plugin_theme_email() with types success, fail, or mixed.

auto_plugin_update_send_email and auto_theme_update_send_email receive ( $enabled, $slice ) where $slice is $update_results['plugin'] or $update_results['theme'] (arrays of result objects for that type), not the full $update_results tree. auto_plugin_theme_update_email adjusts the final email payload.

The auto_plugin_theme_update_emails value is stored with get_option() and update_option() (per-site options API), not get_site_option(), when tracking failure versions to limit repeat messages. WordPress 6.6+ messaging may include rollback outcomes after fatal loopback.

Process flow

  1. A batch completes.
  2. Core decides whether to email.
  3. Filters adjust or suppress the email.
  4. WordPress sends the mail to the admin email unless a filter prevents it.

Reference

HookTypeParametersNotes
auto_plugin_update_send_emailfilterbool, arrayPlugin batch email gate; second argument is the plugin result list only
auto_theme_update_send_emailfilterbool, arrayTheme batch email gate; second argument is the theme result list only
auto_plugin_theme_update_emailfilterarrayFinal to, subject, body, and headers

Developer resources


4.6 Debug emails (development builds)

Development WordPress builds may send a debug log email after background updates when enabled.

How it works

If the site runs a development version (a version string containing a hyphen, such as a release candidate suffix) and background update results exist, core may send a debug email. The filter automatic_updates_send_debug_email defaults to true only on development versions. The filter automatic_updates_debug_email adjusts the debug mail payload.

Process flow

  1. A background batch finishes on a development build.
  2. The debug email path evaluates filters.
  3. An optional email sends with diagnostic content.

Reference

HookTypeParametersNotes
automatic_updates_send_debug_emailfilterboolEnables debug email
automatic_updates_debug_emailfilterarrayAdjusts the email payload

Developer resources


4.7 automatic_updates_complete: the results payload

The automatic_updates_complete action passes a structured array of results for logging and external notifications. When you consume this hook, inspect types, result objects, and error codes carefully.

How it works

do_action( 'automatic_updates_complete', $update_results ) fires at the end of WP_Automatic_Updater::run() when results exist. The array matches the internal update_results property. Top-level keys are update type strings: core, plugin, theme, and translation. A key exists only if the batch attempted at least one update of that type. Each value is a numerically indexed array of result objects.

When messages and result conflict on failure: When an attempt fails with a WP_Error on result (common example: code fs_unavailable when WP_Filesystem cannot initialize), messages may still contain earlier or generic skin output — sometimes success-adjacent copy (such as “the site already has the latest version”) that does not reflect the actual failure. If you build operator-facing diagnostics, inspect result with is_wp_error() and surface the error code and message, not only implode() of messages. The automatic-update debug email text draws from structured outcomes and WP_Error; achieving parity with that journal requires merging both sources.

Rollback signals: Core may set result to WP_Error with code rollback_was_required when Core_Upgrader rolls back after failure. Plugin automatic updates on WordPress 6.6+ may use codes such as plugin_update_fatal_error_rollback_successful or plugin_update_fatal_error_rollback_failed on the same result property, with item identifying the plugin.

Process flow

  1. The batch run finishes.
  2. Core populates result objects per attempt.
  3. automatic_updates_complete fires only if $update_results is non-empty at the end of run(). Otherwise, listeners never run.
  4. Your plugin can handle logging or outbound integrations from this hook.

Reference

Top-level shape:

ShapeDetails
Top-level keys'core', 'plugin', 'theme', 'translation' — present only if attempted
Each valueNumeric array of result objects

Each result object:

PropertyTypeDescription
itemobjectUpdate offer from the relevant transient
resulttrue, WP_Error, or other falsy valueSuccess is typically boolean true; failures are usually WP_Error; other falsy values may indicate failure without a WP_Error in edge cases
namestringHuman-readable label
messagesarrayStrings from the Automatic_Upgrader_Skin message buffer

Typical item fields by type:

TypeIdentifiersVersion or packageOther (non-exhaustive)
corecurrent (offered ZIP version), often version displayresponse (autoupdate for automatic candidates), locale, php_version, mysql_version, new_files, download URLs, autoupdate, disable_autoupdate when present
pluginplugin, slugnew_versionpackage, url, id, requires_php, autoupdate, disable_autoupdate
themetheme (stylesheet slug)new_versionpackage, url, requires_php, autoupdate, disable_autoupdate
translationtype (core, plugin, or theme), slug, languageversionpackage, autoupdate — objects from translation arrays through wp_get_translation_updates()

Developer resources


4.8 Fatal error recovery email (WP_Recovery_Mode)

Fatal errors during bootstrap can trigger Recovery Mode, which emails a login link. This path is separate from automatic updater email.

How it works

WP_Recovery_Mode in wp-includes/class-wp-recovery-mode.php handles detection and email when a fatal error breaks the site after a change. Its triggers, options, and messaging differ from WP_Automatic_Updater emails. Do not conflate the two when debugging post-update failures.

Process flow

  1. A fatal error occurs.
  2. Recovery Mode may activate.
  3. WordPress emails the site administrator with a secure login link.
  4. The administrator resolves the fault using the recovery link.
  5. This process is separate from background update success or failure emails.

Reference

ClassFileExtendsRole
WP_Recovery_Modeclass-wp-recovery-mode.phpFatal recovery and email

Developer resources


Author

Photo de Quentin Le Duff

Quentin Le Duff

Quentin Le Duff is a WordPress developer for ten years, Opquast® Expert & ISTQB certified. He works with WordPress every day: developing open source plugins and themes, hosting and maintaining his clients’ websites, and writing about the WP ecosystem.