You went to update WordPress, a plugin, or a theme, and you got this:
> Another update is currently in progress.
The site still loads. Nothing is broken. But every update you try – core, plugins, themes – bounces with the same message. The fix is one of these, in order of effort:
- Wait 15 minutes. WordPress auto-clears the lock since version 4.5.
- WP-CLI:
wp option delete core_updater.lock - SQL (phpMyAdmin or MySQL CLI):
DELETE FROM wp_options WHERE option_name = 'core_updater.lock'; - Drop a one-shot mu-plugin that calls
delete_option('core_updater.lock').
Pick the route you have access to and the error is gone on the next update attempt. The rest of this guide explains what the lock is, why WordPress sets it, why it sometimes gets stuck, and how to keep it from happening again.
What the lock actually is#
WordPress runs core, plugin, and theme upgrades inside a class called
WP_Upgrader
. The first thing it does when you click Update Now is set a row in the
wp_options
table called
core_updater.lock
, with the current Unix timestamp as the value. Before any other update can start, WordPress checks that row. If it exists and is recent, the upgrader bails out with the error you are looking at.
The lock is a mutex. It exists so that two simultaneous upgrade processes cannot fight over the same files. Imagine two cron jobs firing at once, each trying to overwrite
wp-includes/version.php
– you would end up with a corrupted core install. The lock guarantees that only one upgrader runs at a time per site.
Under normal conditions WordPress sets the lock at the start of an update and deletes it at the end. The error you are seeing means the second half never happened.
Why the lock gets stuck#
Anything that kills the PHP request mid-update leaves the lock in place. The most common causes:
- PHP timeout. The update takes longer than
max_execution_time(often 30 or 60 seconds on shared hosting). Downloading core or a large plugin can cross that threshold on a slow connection. - Memory exhausted. WordPress runs out of
WP_MEMORY_LIMITor PHP’smemory_limitmid-upgrade and the request dies. - Browser tab closed. You hit Update, got bored, closed the tab. The PHP-FPM worker may finish or may not, depending on how the host handles disconnected requests.
- Server restart, deploy, or container respawn during the update. The PHP process is killed before it can clean up.
- Auto-update fired in the background and crashed. The WordPress cron picks up a pending auto-update, runs it via WP-Cron, and the request times out with no one watching.
- Two updates raced. You triggered an update from the dashboard while WP-Cron was already running one in the background. Whichever one started second hit the lock and aborted, but the first one might have crashed too.
You will rarely know which of these caused it. You do not need to. The fix is the same.
Method 1: wait it out#
Since WordPress 4.5, the upgrader treats any
core_updater.lock
row older than 15 minutes (
MINUTE_IN_SECONDS * 15
) as expired and ignores it. After 15 minutes, the next update attempt overwrites the row and proceeds normally.
If the site is not on fire and you can wait, this is the right answer. No SSH, no database, no risk of typing the wrong table prefix.
The clock starts when the original failed update kicked off, not when you saw the error. If you are not sure when that was, check the timestamp:
SELECT option_value, FROM_UNIXTIME(option_value) AS started_at
FROM wp_options
WHERE option_name = 'core_updater.lock';
If
started_at
is more than 15 minutes ago and you are still hitting the error, your WordPress version may be older than 4.5 – or your WordPress install is below the 4.5 line, which means it is also missing several years of security patches and you should update it the moment the lock clears.
Method 2: WP-CLI (cleanest)#
If you have shell access:
wp option delete core_updater.lock
That is it. Re-run your update from the dashboard or with
wp core update
/
wp plugin update --all
.
If the lock came from an automatic update rather than a manual one, the option name might be
auto_updater.lock
instead. List anything matching to be sure:
wp option list --search="*updater*lock*"
Delete each one you find:
wp option delete auto_updater.lock
wp option delete core_updater.lock
WP-CLI ships on every Hostney plan and on most managed WordPress hosts. If you have never used it before, see how to install WordPress with WP-CLI for the basics – the same command pattern works for everything else.
Method 3: phpMyAdmin or the MySQL CLI#
If you do not have WP-CLI but you do have database access, run a
DELETE
against
wp_options
:
DELETE FROM wp_options WHERE option_name = 'core_updater.lock';
If your table prefix is not
wp_
(it often is not – many installers randomize it for security), adjust accordingly. The prefix is in
wp-config.php
on the line that looks like:
$table_prefix = 'wp_';
In phpMyAdmin: open your site’s database, click the
wp_options
table, hit the Search tab, type
core_updater.lock
in the
option_name
field, find the row, and delete it. One row, one click.
While you are in
wp_options
, also look for
auto_updater.lock
and any other
*_updater.lock
rows. Delete the ones that look stale.
Method 4: a one-shot mu-plugin#
If you have FTP/SFTP but no shell and no phpMyAdmin, you can delete the lock from PHP. Drop a file into
wp-content/mu-plugins/
(create the directory if it does not exist) called
clear-update-lock.php
:
<?php
delete_option('core_updater.lock');
delete_option('auto_updater.lock');
Visit any page on the site to trigger it, then delete the file. mu-plugins (must-use plugins) load on every request, no activation needed, so a single page load runs it.
If you do not want to write PHP, you can do the same thing from a file manager – though you should not need to. Hostney’s WordPress file manager handles this in a browser without an FTP client.
What to do after the lock is cleared#
The lock being stuck means the original update did not finish. Before you call the site healthy:
- Check what version is actually installed. Run
wp core versionor look at the bottom right of Dashboard > Updates. If it does not match what you tried to update to, the original upgrade failed mid-flight. - Re-run the update. From Dashboard > Updates, or
wp core update/wp plugin update <slug>/wp theme update <slug>. This time it will proceed. - Check the site loads. Front end, admin, and a couple of inner pages. Half-applied plugin updates can leave the database in a state the new code does not expect, and the easiest way to spot that is to actually click around.
- If the site does not load, you may be looking at a deeper failure – see my WordPress site is down: a diagnostic checklist for the usual suspects.
- Clear caches. Page cache, object cache, CDN, browser. A half-finished update plus stale cache makes diagnostics much harder. See how to clear the WordPress cache, every layer explained.
If the original update failed because of a PHP version mismatch or a memory exhaustion, re-running it without fixing the underlying cause will just leave the same lock again 30 seconds later. Check error logs first.
How to stop it from happening again#
A stuck lock is almost always a symptom of an interrupted update, not a WordPress bug. Reduce the interruptions and you stop seeing the error.
- Do not close the browser tab during a manual update. Let it finish and show you the success screen.
- Raise
max_execution_timefor the admin context. 30 seconds is not enough for a multi-megabyte plugin update on a slow link. 120 seconds is a saner default. - Raise
WP_MEMORY_LIMITand PHPmemory_limit. WordPress recommends at least 256M for the admin side. The defaults on cheap shared hosting are sometimes 64M, which is enough for the front end but not for upgrades. - Do not deploy or restart the server while an update is running. Obvious in hindsight, but a CI pipeline that triggers a container respawn at 2:05 AM while WP-Cron’s auto-update runs at 2:00 AM will reproduce this every week.
- Test major updates on a staging site. A staging copy lets the failed update happen somewhere that does not block your production updater. See how to create a WordPress staging site.
- Take a snapshot before manual major updates. If the upgrade fails halfway, you restore the snapshot instead of debugging which files made it onto disk.
A failed update is not an emergency, but a half-finished one is. The lock is WordPress’s way of insisting that you finish what you started before you start something else.
How Hostney handles this#
On Hostney, managed WordPress updates run inside a configurable quiet-hours window, with a deliberate delay after each release (1 day for minor core, 5 days for major, 2 days for plugins and themes – all per-installation, all editable in the panel). The point of the delay is to let regressions surface on other people’s sites first before they reach yours.
Every managed update is preceded by an automatic snapshot. If an update fails halfway, you restore the snapshot from the Snapshots tab in one click – no database surgery, no
core_updater.lock
to delete, no “did it actually finish?” guessing. The snapshot is the rollback.
The PHP environment is also tuned for the admin context:
max_execution_time
and
memory_limit
are set high enough that an interrupted update is rare in the first place. When updates do get killed – container respawn, network blip – the snapshot is the safety net. You are not relying on the lock-clearing dance to recover.
You can override any of this per installation. Auto-update toggles for core minor, core major, plugins, and themes are all separate switches. Set the update window to 3 AM your time, set the delay days to whatever your risk tolerance is, and let the platform do the rest.
If you would rather test updates before they hit production, every site gets a one-click staging environment – run the update there first, verify the site, then promote.
Summary#
The “another update is currently in progress” error is a stale
core_updater.lock
row in
wp_options
. Wait 15 minutes for it to expire on its own, or delete it via WP-CLI, SQL, or a mu-plugin and re-run the update. The lock exists to prevent two updates from racing, and it gets stuck whenever a PHP timeout, memory limit, browser disconnect, or server restart kills the upgrade mid-flight. Fix the underlying cause – bigger memory limit, longer execution time, snapshot-then-update workflow – and you will rarely see it again.