Updates and Auto-Updates
|
This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production. This sub-section’s WordPress bibliography lists the reference material consulted while preparing these pages. |
This page was written against WordPress 7.1.3 (released 2026-10-06; 7.1.4, a security release of 2026-10-28, is the
version to run in production) and WP-CLI 2.12.0, and checked on 2026-10-28.
WordPress 7.1 requires PHP 7.4 at minimum, and PHP 8.3 or newer is recommended. WordPress 7.2 is in beta and due in
December 2026; nothing in its betas changes the update mechanisms described here. Every command and wp eval-file
probe below was run against a WordPress site in Docker (MariaDB 11.8, the wordpress:cli-2.12.0-php8.4 image, and
wordpress:7.1.3-php8.4-apache where a web server was needed), first installed at 7.1.2 so that real updates to 7.1.3
were available. Every output block is real output, shortened only where marked.
Updates are the most effective security measure a WordPress site has: most compromised sites run an outdated plugin,
theme or core version. This page is for administrators who decide how a site is updated: what WordPress updates on its
own, how to change that with constants and filters, the emails it sends, the 6.6 rollback, and how Lumen Press updates
staging and production. Version numbers (X.Y is a major release, X.Y.Z a minor one), the release cadence and beta
builds are in Versions and Release Cycle; the per-plugin and
per-theme Enable auto-updates toggles, wp plugin auto-updates and the 6.3 rollback of failed manual updates are in
Choosing and Managing Plugins and Themes.
What gets updated, and by whom
WordPress distinguishes five kinds of update. Each has its own default and its own switch.
| Kind | Default since | Who decides | Main switch |
|---|---|---|---|
Minor core release (7.1.2 to 7.1.3): maintenance and security fixes |
Automatic since 3.7 |
WordPress, unless the site opts out |
|
Major core release (7.1 to 7.2) |
Automatic for sites installed on 5.6 or later; existing sites were left unchanged by the 5.6 upgrade and can opt in |
The administrator on Dashboard > Updates, or code |
|
Development core build (beta, RC, nightly), only on sites already running one |
Automatic since 3.7 |
WordPress |
|
Plugins and themes |
Manual, unless the administrator enables the toggle (5.5+) or WordPress.org forces a security release |
The administrator, per item; the WordPress.org security team for forced releases |
|
Translations (language packs for core, plugins and themes) |
Automatic since 3.7 |
WordPress |
|
Security releases are minor releases, so this default applies them without anyone acting: WordPress 7.1.4, a security-only release published on 2026-10-28 (it fixes a remote code execution weakness in the upgrade process and a series of stored XSS issues), was offered to every 7.1 site as a minor update, and the announcement notes that sites with automatic background updates would start updating automatically; on a site that opted out, update to it immediately. Source: WordPress News: WordPress 7.1.4
The 5.6 rule comes from three site options. A fresh install writes auto_update_core_dev, auto_update_core_minor and
auto_update_core_major, all enabled; the database upgrade to 5.6 wrote auto_update_core_major as unset on
existing sites, which counts as "off". On the test site, freshly installed at 7.1.2:
wp option list --search='auto_update*'
wp core check-update
option_name option_value
auto_update_core_dev enabled
auto_update_core_major enabled
auto_update_core_minor enabled
version update_type package_url
7.1.3 minor https://downloads.wordpress.org/release/wordpress-7.1.3-partial-2.zip
The package is a partial build: only the files that changed between 7.1.2 and 7.1.3. Core falls back to the full package when the partial one cannot be used.
The Dashboard > Updates screen
Dashboard > Updates (wp-admin/update-core.php) handles every kind of update. Under "Last checked on … at …" and
a Check again link, it has four sections. WordPress offers Update to version 7.1.3, or Re-install version 7.1.3
(a repair for modified or corrupt core files), and a status line with the core policy: "This site is automatically kept
up to date with each new version of WordPress." or "…with maintenance and security releases of WordPress only." A
link switches between the two by writing auto_update_core_major as enabled or disabled. Plugins, Themes and
Translations list pending updates with Update Plugins, Update Themes and Update Translations buttons.
The policy link disappears when the policy is decided in code: when WP_AUTO_UPDATE_CORE is defined, when the whole
updater is disabled, or when any code is hooked to allow_major_auto_core_updates. If a version-control checkout is
detected, the status line reads "This site appears to be under version control. Automatic updates are disabled."
Only users with the update_core, update_plugins, update_themes and update_languages capabilities see the screen
and its notices, which by default means Administrators on a single site and only Super Admins on Multisite, where the
screen lives in the Network Admin (see Multisite Networks).
Other routes: an update now link on each row of Plugins and Appearance > Themes; WP-CLI for scripted updates
(Updating with WP-CLI); hosting panels such as WP Toolkit in cPanel and Plesk, whose schedules run alongside core’s
updater unless the host disables it (find out which one is in charge); and the manual update (replace everything except
wp-config.php and wp-content/, then visit /wp-admin/upgrade.php) for servers where nothing else works.
How background updates run
Background updates are driven by WP-Cron. On init, wp_schedule_update_checks() schedules three twice-daily events:
wp_version_check, wp_update_plugins and wp_update_themes. When wp_version_check() runs inside a cron request,
it fires the wp_maybe_auto_update action, whose callback creates a WP_Automatic_Updater and calls its run()
method. A site whose WP-Cron does not run (disabled with DISABLE_WP_CRON and no system cron, or a site without
traffic) never updates itself; see WP-Cron and Scheduled Tasks.
run() returns at once if the updater is disabled, if the site is not the main site of the main network, or if another
run holds the auto_updater.lock option (it expires after one hour). Otherwise it updates eligible plugins, then
themes, then core (find_core_auto_update(), under its own 15-minute core_updater.lock), then translations, and
finally sends the emails and fires automatic_updates_complete with every result.
Before each plugin, theme or core update, the site is put in maintenance mode: a .maintenance file in the WordPress
root makes every front-end and admin request answer "Briefly unavailable for scheduled maintenance. Check back in a
minute." The file is deleted at the end; if a run dies half-way the file stays, but WordPress ignores it once it is
more than ten minutes old.
The decision chain for one update
For each offer, WP_Automatic_Updater::should_update() decides whether to install it. The tree below follows the code
of WordPress 7.1.3; the filters are where a site’s own policy enters.
Three details of the chain are easy to miss:
-
The
auto_update_{$type}filters run after the built-in decision and receive it as$update, so a filter can both grant and refuse. Returningfalsefromauto_update_pluginalso refuses the security releases that WordPress.org forces. -
For core, the built-in decision is
Core_Upgrader::should_update_to_version(). It compares the branch (the first two numbers) of the running and offered versions: same branch is a minor update, a newer branch is a major one, and a running version with a hyphen (7.2-beta2) is a development version. It also refuses an offer after a critical earlier failure (see Update emails). -
The
new_filesflag of a core offer relaxes the file-ownership check for partial builds that add no new files.
Constants in wp-config.php
| Constant | Values | Effect |
|---|---|---|
|
|
|
|
|
Turns the background updater off entirely: no core security releases, no translations, no plugin or theme updates, and no update emails. The handbook strongly discourages it. |
|
|
Refuses every file change made by WordPress: installing, uploading, updating and deleting plugins and themes, the
file editors, and the background updater ( |
|
|
How WordPress writes files. Background updates only run when no credentials are needed, which normally means the PHP
user owns the files ( |
|
|
A major update does not install newly bundled default themes and plugins |
Lumen Press production defines DISALLOW_FILE_MODS (see
Security Hardening): its code is owned by a deploy user, PHP writes only
uploads, and every update, security releases included, reaches it through the deployment pipeline after staging has
taken it. The background updater therefore runs on staging, where WordPress updates itself in place, and on any
classically maintained site. The staging configuration keeps only the constants that must hold even if a must-use
plugin is missing:
<?php
// wp-config.php (Lumen Press staging), above the "That's all, stop editing!" line.
define( 'WP_ENVIRONMENT_TYPE', 'staging' );
define( 'WP_AUTO_UPDATE_CORE', 'minor' ); // Minor releases even without the policy plugin, which adds major ones.
define( 'FS_METHOD', 'direct' ); // On staging the PHP-FPM user owns the WordPress files.
Filters in a must-use plugin
Constants are coarse; filters can decide per environment, per item and per day. They belong in a must-use plugin in
wp-content/mu-plugins/, never in wp-config.php: WordPress is not fully loaded while wp-config.php runs, so
add_filter() there is fragile and the handbook notes it conflicts with WP-CLI. A must-use plugin cannot be deactivated
from the dashboard, which is what an update policy needs. Must-use plugins themselves are explained in
Choosing and Managing Plugins and Themes.
| Hook | Use |
|---|---|
|
Return |
|
Final yes or no per offer; receives the built-in decision and the offer object ( |
|
Simpler core switches applied inside |
|
Override version-control detection (see Version-control checkouts) |
|
Turn each kind of update email off; change its recipients, subject, body or headers |
|
Fires just before each automatic update, with the type, offer and filesystem context |
|
Fires after a run with every attempted update and its result |
The Lumen Press policy lives in wp-content/mu-plugins/lumen-update-policy.php on every site the updater maintains
(on production DISALLOW_FILE_MODS makes it inert). It complements the site’s plugin policy
(the "always update Two Factor and Akismet, never auto-update themes" filters shown on the plugins page): minor core
releases everywhere, major releases automatically only on staging, translations always, no plugin or theme updates at
weekends when nobody is on call, no routine "success" emails, and a log line for every run.
<?php
/**
* Plugin Name: Lumen Update Policy
* Description: Background update policy for Lumen Press: minor core releases everywhere, major releases only on staging, translations always, no plugin or theme updates at weekends, quieter emails.
* Version: 0.1.0
* Author: Lumen Press
* License: GPL-2.0-or-later
*/
defined( 'ABSPATH' ) || exit;
// Major core releases: staging takes them automatically, production gets them by deployment once tested.
add_filter(
'allow_major_auto_core_updates',
static function () {
return 'staging' === wp_get_environment_type();
}
);
// Minor (maintenance and security) core releases: always.
add_filter( 'allow_minor_auto_core_updates', '__return_true' );
// Translations: always.
add_filter( 'auto_update_translation', '__return_true' );
// Plugins and themes: no automatic updates at weekends, when nobody is on call.
// Priority 20 runs after filters that force updates on (such as the site policy plugin).
$lumen_weekdays_only = static function ( $update ) {
return (int) wp_date( 'N' ) >= 6 ? false : $update;
};
add_filter( 'auto_update_plugin', $lumen_weekdays_only, 20 );
add_filter( 'auto_update_theme', $lumen_weekdays_only, 20 );
// Core emails: keep failures ("fail", "critical"), drop the routine "success" message.
add_filter(
'auto_core_update_send_email',
static function ( $send, $type ) {
return 'success' === $type ? false : $send;
},
10,
2
);
// Leave a trace of every background run in the PHP error log.
add_action(
'automatic_updates_complete',
static function ( $results ) {
foreach ( $results as $type => $items ) {
foreach ( $items as $item ) {
$outcome = is_wp_error( $item->result ) ? $item->result->get_error_code() : 'ok';
error_log( sprintf( '[lumen-updates] %s %s: %s', $type, $item->name, $outcome ) );
}
}
}
);
The weekend rule also holds back forced security releases of plugins until Monday; checks run twice a day, so the delay is at most about two days. A site that cannot accept that delay should drop the rule.
Verifying the policy against WP_Automatic_Updater
Reading filters is not proof of what the updater will do. This probe asks WP_Automatic_Updater itself, through
should_update(), about four hypothetical offers: a minor core release, a major one, a plugin and a translation.
Nothing is downloaded or installed. Keep it outside the web root and run it with wp eval-file.
<?php
/*
* Asks WP_Automatic_Updater what it would do with a few hypothetical update offers.
* Nothing is downloaded or installed. Run with: wp eval-file update-probe.php
*/
require_once ABSPATH . 'wp-admin/includes/admin.php';
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
$updater = new WP_Automatic_Updater();
$answer = static function ( $value ) {
return $value ? 'yes' : 'no';
};
$core_offer = static function ( $version ) {
return (object) array(
'current' => $version,
'version' => $version,
'php_version' => '7.4',
'mysql_version' => '5.5.5',
'new_files' => true,
);
};
$offers = array(
array( 'core', $core_offer( '7.1.4' ), ABSPATH ),
array( 'core', $core_offer( '7.2' ), ABSPATH ),
array( 'plugin', (object) array( 'slug' => 'two-factor', 'plugin' => 'two-factor/two-factor.php' ), WP_PLUGIN_DIR ),
array( 'translation', (object) array( 'type' => 'core', 'language' => 'es_ES', 'autoupdate' => true ), WP_CONTENT_DIR ),
);
printf( "%-22s %s\n", 'environment', wp_get_environment_type() );
printf( "%-22s %s\n", 'running version', wp_get_wp_version() );
printf( "%-22s %s\n", 'updater disabled', $answer( $updater->is_disabled() ) );
printf( "%-22s %s\n", 'VCS checkout', $answer( $updater->is_vcs_checkout( ABSPATH ) ) );
foreach ( $offers as list( $type, $item, $context ) ) {
$label = 'core' === $type ? "core {$item->current}" : "{$type} " . ( $item->slug ?? $item->language );
printf( "%-22s %s\n", $label, $answer( $updater->should_update( $type, $item, $context ) ) );
}
On the 7.1.2 test site, freshly installed and without any policy:
environment production
running version 7.1.2
updater disabled no
VCS checkout no
core 7.1.4 yes
core 7.2 yes
plugin two-factor no
translation es_ES yes
Changing one thing at a time gave the results below. The third row shows that filters win over the constant:
allow_minor_auto_core_updates returning true re-enables minor updates although WP_AUTO_UPDATE_CORE is false.
| Configuration | core 7.1.4 | core 7.2 | plugin | translation |
|---|---|---|---|---|
|
no |
no |
no |
yes |
Lumen policy, |
yes |
no |
no |
yes |
Lumen policy, |
yes |
yes |
no |
yes |
|
yes |
no |
no |
yes |
|
no |
no |
no |
no |
|
no |
no |
no |
no |
Lumen policy, Two Factor toggled on ( |
yes |
no |
yes |
yes |
Same, with |
yes |
no |
no |
yes |
Lumen policy, toggle on, |
yes |
no |
no |
no |
Same, |
no |
no |
no |
no |
Same, plus the VCS override plugin shown in Version-control checkouts |
yes |
no |
yes |
yes |
AUTOMATIC_UPDATER_DISABLED and DISALLOW_FILE_MODS beat every filter that grants an update, because
is_disabled() is checked first; only the automatic_updater_disabled filter can override the former, and only the
file_mod_allowed filter the latter.
Version-control checkouts
An updater that rewrites files would fight a deployment that also writes them. So is_vcs_checkout() looks for a
.svn, .git, .hg or .bzr directory in the update’s context directory and in every parent up to the filesystem
root, and always also in ABSPATH and its parents. When one is found the update is skipped; for a core offer, WordPress
falls back to sending the "WordPress x.y.z is available" email (if WordPress.org flags the release). Directories outside
PHP’s open_basedir are not checked (since 6.2).
The context differs by type: ABSPATH for core, WP_PLUGIN_DIR for plugins, the theme root for themes and
WP_CONTENT_DIR for translations. The last three rows of the probe table above show the effect: a repository that
versions only wp-content (the usual layout, see
Deployment and CI/CD) blocks plugin, theme and translation updates but not
core security releases. A .git anywhere above the WordPress root, such as a whole server directory under
version control, blocks everything. Site Health reports it under Background updates as "The folder … was detected as
being under version control (.git)."
If the checkout is deliberate but WordPress may still update (a server where a configuration repository happens to sit
above the site, for example), return false from automatic_updates_is_vcs_checkout, at priority 1 as the handbook
recommends, so that later callbacks can still say true for specific paths:
<?php
/**
* Plugin Name: Lumen VCS Override
* Description: The release tag is checked out with Git, but WordPress may still apply security releases.
*/
defined( 'ABSPATH' ) || exit;
add_filter( 'automatic_updates_is_vcs_checkout', '__return_false', 1 );
Lumen Press does not need the override: its production servers receive releases by rsync of a build without .git
and define DISALLOW_FILE_MODS, and on staging its update policy alone decides.
Update emails
All update emails go to the address in the admin_email option (Settings > General, "Administration Email Address"),
not to every administrator. They are sent with wp_mail(), so a site that cannot send mail (see
Email Delivery) silently loses them.
| Sent when | Filter to turn it off | |
|---|---|---|
"[Site] Your site has updated to WordPress 7.1.3" |
A background core update succeeded |
|
"[Site] WordPress 7.1.3 is available. Please update!" |
A core update failed early ( |
|
"[Site] URGENT: Your site may be down due to a failed update" |
A core update failed after files started to be copied ( |
|
"[Site] Some plugins were automatically updated", "…have failed to update", "Some plugins and themes have automatically updated" and similar |
After any plugin or theme auto-update, one summary per run |
|
Debug email with the full log of the run |
After every run on a development version (a hyphen in the version, such as |
|
The success email from a real background update of the test site from 7.1.2 to 7.1.3 (captured with a pre_wp_mail
filter in a test-only must-use plugin, without the Lumen policy that suppresses it):
TO: admin@lumenpress.test
SUBJECT: [Lumen Press] Your site has updated to WordPress 7.1.3
Howdy! Your site at https://lumenpress.test has been updated automatically to WordPress 7.1.3.
No further action is needed on your part. For more on version 7.1.3, see the About WordPress screen:
https://lumenpress.test/wp-admin/about.php
(support forum links and signature)
With the Lumen policy active, the same update sent nothing, left [lumen-updates] core WordPress 7.1.3: ok in
wp-content/debug.log, and still recorded "type":"success" with the address and version in the
auto_core_update_notified site option, which is how WordPress avoids repeating an email.
Core failures are also remembered, in the auto_core_update_failed site option. A critical failure (disk_full, an
error while copying files, or a failed internal rollback) stops all later core auto-updates until an administrator
completes a manual update. A non-critical one stops retrying that same version; download_failed,
incompatible_archive, insane_distro and locked are retried once after an hour. After fixing the cause,
wp option get auto_core_update_failed shows what happened, and a successful wp core update clears the block.
Rollback of failed updates
Three mechanisms exist, each narrow:
-
Core, since 3.7: core updates started by the background updater run with
attempt_rollback. If copying the new files fails, WordPress re-installs the current version from arollbackpackage and records therollback_was_requirederror ("Due to an error during updating, WordPress has been restored to your previous version."), which the failure email reports. Only a rollback that fails too counts as critical. It does not detect a new version that installs cleanly but breaks the site. -
Plugins and themes, manual updates, since 6.3: the old copy is kept in
wp-content/upgrade-temp-backup/and put back if the installation itself fails. -
Plugins, automatic updates, since 6.6: after auto-updating a plugin that was active, WordPress keeps the site in maintenance mode, waits two seconds and requests the home page with a scrape key. If the response contains a PHP fatal error, the old version is restored from the temporary backup, the error log says the update "contained a fatal error", and the plugin appears in the summary email ("Some plugins have failed to update") under "The following plugins failed to update. If there was a fatal error in the update, the previously installed version has been restored." The same plugin is offered again at the next check.
The second and third are described with their limits (inactive plugins and themes are not checked, non-fatal breakage is not detected, database changes are not undone) in Choosing and Managing Plugins and Themes.
One more limit matters to administrators: a loopback request that fails counts as a fatal error. has_fatal_error()
returns true when wp_remote_get() to the home URL returns an error. On the test site, whose home URL
(https://lumenpress.test) the server could not reach on port 443, every auto-update of the active Two Factor plugin
was undone although 0.17.0 has no fatal error (log from WP_DEBUG_LOG with timestamps removed, and the Lumen
policy’s log line at the end):
Automatic updates starting...
Automatic plugin updates starting...
Upgrading plugin 'two-factor'...
Plugin 'two-factor' has been upgraded.
Scraping home page...
Loopback request failed: cURL error 7: Failed to connect to lumenpress.test:443 after 2 ms: Could not connect to server
The update for 'two-factor' contained a fatal error. The previously installed version has been restored.
Automatic plugin updates complete.
Automatic updates complete.
[lumen-updates] plugin Two Factor: plugin_update_fatal_error_rollback_successful
Afterwards wp plugin list still showed 0.16.0, active, with 0.17.0 available. With the home URL reachable from the
server, the same update was kept ("The update for 'two-factor' has no fatal errors."). Behind a load balancer, a
firewall that blocks the server’s own requests, HTTP basic auth (only forwarded when the cron request itself carried
it) or a split DNS, active plugins therefore never auto-update, and the emails report them as failed. Check Tools >
Site Health ("Your site can perform loopback requests") on every environment that auto-updates plugins; see
Debugging, Site Health and Troubleshooting.
Updating safely
Automatic minor updates are low-risk and should stay on. Major releases, plugin and theme updates, and anything on a site with custom code deserve a process. Lumen Press follows this one:
-
Staging first: a copy of production with the same PHP version and plugins, refreshed from a production backup (see Importing, Exporting and Migrating). It takes major releases as soon as they ship; the team tests the catalogue, the
lumen/latest-booksblock, thelumen/v1REST API and the WooCommerce checkout (see Cart and Checkout Blocks) there. -
Back up and verify the backup (database and
wp-content); see Backups and Disaster Recovery. -
Read the changelogs and, for a major release, the Field Guide: removed functions, new PHP minimums, database upgrades.
-
Update in a quiet window: plugins and themes that support the new version, then core, then translations, then the database upgrade.
-
Go step by step across large jumps: one-click updates from 3.7 onwards are safe, but the handbook recommends incremental upgrades more than two major releases apart, checking each step’s PHP and database needs (see Requirements and Hosting).
-
Watch the error log and the admin mailbox for a day.
Updating with WP-CLI
WP-CLI makes each step scriptable and repeatable. The run below took the test site from 7.1.2 to 7.1.3 and updated Two Factor from 0.16.0. It runs as the user that owns the WordPress files; run as another user, WP-CLI creates files that PHP later cannot update. The full command reference is in WP-CLI.
wp core check-update
wp plugin list --update=available --fields=name,version,update_version,auto_update
wp db export - | gzip > "lumen-pre-update-$(date +%F).sql.gz" # outside the web root
wp core update --minor
wp core update-db
wp plugin update --all --exclude=lumen-catalog
wp theme update --all
wp language core update
wp core verify-checksums
wp plugin verify-checksums --all
Source: WP-CLI Commands: wp core update
version update_type package_url
7.1.3 minor https://downloads.wordpress.org/release/wordpress-7.1.3-partial-2.zip
name version update_version auto_update
two-factor 0.16.0 0.17.0 on
Updating to version 7.1.3 (en_US)...
Downloading update from https://downloads.wordpress.org/release/wordpress-7.1.3-partial-2.zip...
Unpacking the update...
(40 lines of HTML from the plugin and theme translation updates that follow a core update)
Success: WordPress updated successfully.
Success: WordPress database already at latest db version 61833.
Enabling Maintenance mode...
Downloading update from https://downloads.wordpress.org/plugin/two-factor.0.17.0.zip...
Unpacking the update...
Installing the latest version...
Removing the old version of the plugin...
Plugin updated successfully.
Disabling Maintenance mode...
name old_version new_version status
two-factor 0.16.0 0.17.0 Updated
Success: Updated 1 of 1 plugins.
Skipped updates for: lumen-catalog
Success: Theme already updated.
Updating 'Spanish (Spain)' translation for WordPress 7.1.3...
(4 progress lines)
Success: Updated 1/1 translation.
Success: WordPress installation verifies against checksums.
Success: Verified 3 of 3 plugins.
Notes on the commands:
-
wp core updateupdates to the latest release, including a new major one;--minorstays on the current branch and--version=<x.y.z>picks a version.wp core update-dbruns the schema upgrade that the dashboard runs from/wp-admin/upgrade.php; a minor release rarely needs one ("already at latest db version"), a major one often does. On Multisite,wp core update-db --networkupgrades every site. -
After a core update, WordPress updates plugin and theme translations on its own; WP-CLI prints that step as HTML. In the test run the core translation still needed
wp language core update;wp language plugin update --allandwp language theme update --allcover the rest. -
--excludekeeps private plugins that are deployed from Git, such aslumen-catalog, out of the run; WP-CLI reports them as skipped.wp plugin update --all --dry-runlists what would change without changing it. -
wp plugin updateputs the site in maintenance mode around each plugin. For a longer window,wp maintenance-mode activateanddeactivatedo the same by hand. -
verify-checksumscompares files with WordPress.org’s checksums. It is the quickest proof that an update finished and that nobody altered core or a directory plugin.
Triggering a background run on purpose
To test a policy or reproduce a failed auto-update, run the cron event that a real background run starts from, rather than calling the updater directly:
wp cron event run wp_version_check # Executed the cron event 'wp_version_check' in 5.541s.
wp cron event run defines DOING_CRON, so the run behaves as in production: Two Factor was updated, checked by the
loopback and left active. Calling wp eval 'wp_maybe_auto_update();' also updates, but outside cron
Plugin_Upgrader deactivates each plugin before replacing it (in a background run it does not, because "we require a
browser to reactivate it"); on the test site, Two Factor ended up updated but inactive. To see what the updater logs,
set WP_DEBUG and WP_DEBUG_LOG on a test copy first: every step is written to wp-content/debug.log.
Rolling back core
Downgrading core is discouraged. Newer releases contain security fixes, and a major release can change the database
schema in ways the older code does not understand. If it is unavoidable, the handbook’s procedure is a full restore:
replace the files with the backed-up ones (everything except wp-config.php) and restore the database backup taken
before the update. Without both backups, it calls a successful rollback near impossible.
wp core update --version=7.1.2 --force replaces the files; the test site was moved back that way to repeat the
update, and it worked cleanly only because 7.1.2 and 7.1.3 share a database version (61833). Across a major release,
wp core update-db merely rewrites the stored db_version and leaves the newer schema and data in place; restore the
database instead, as shown in Versions and Release Cycle. With an
automatic minor policy, the site also updates itself again at the next check unless the policy changes.
Re-install version on Dashboard > Updates re-installs the current version only; it is a repair, not a rollback.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
"Briefly unavailable for scheduled maintenance" stays on screen |
An update died and left |
Wait ten minutes (WordPress then ignores the file) or delete it; then repeat the update, because it may be half applied |
"Another update is currently in progress." |
The |
Wait, or |
No automatic update ever happens |
WP-Cron does not run, the updater is disabled, a VCS checkout is detected, or WordPress asks for FTP credentials (file ownership, see File Permissions and Filesystem) |
|
Active plugins are rolled back after every auto-update, with "contained a fatal error" |
The loopback request to the home URL fails |
Make the home URL reachable from the server; check Site Health’s loopback test |
Site Health fails "WordPress security and maintenance releases are blocked by `define( 'WP_AUTO_UPDATE_CORE', false );`" although a filter allows minor updates |
The Site Health test reads the constant only; on the test site the probe confirmed minor updates were still allowed |
Remove the constant and express the policy with filters only, or accept the warning |
Auto-updates stopped after an "URGENT" email |
A critical core failure is recorded in |
Restore the site if needed, then update core manually; the next successful update clears the block |
Where older books are out of date
-
DISALLOW_FILE_MODSis not just "no updates". One older book presents it as the way to turn updates off. It also removes installing, uploading and deleting plugins and themes and the file editors, and it turns off the background updater too, including core security releases. To change only the update policy, useWP_AUTO_UPDATE_COREand filters. -
"Minor" means X.Y.Z. Books that read WordPress versions as major.minor.patch would take
'minor'to mean 7.1 to 7.2. In WordPress, 7.1 to 7.2 is a major release and'minor'allows only 7.1.x releases. -
Major releases update themselves on recent installs. Advice written for older sites assumes only minor releases are automatic; any site installed on 5.6 or later receives major releases automatically unless its policy says otherwise.
-
Plugin auto-updates can roll back. Books written for 6.3 and 6.4 predate the 6.6 rollback of active plugins that cause a fatal error after an auto-update, and its dependency on working loopback requests.
-
Filters go in a must-use plugin, not in
wp-config.phpor a theme’sfunctions.php(a theme switch drops them).