Another Update Is Currently in Progress: How to Fix It

If WordPress tells you another update is currently in progress, nothing is broken and nothing is lost. A single row in your wp_options table called core_updater.lock is telling core that an update is already running, and until that row goes away the updater refuses to start a second one.

Most of the time the row is stale — left behind by an update that died halfway through — and the fix takes one command. But there is a real case where an update genuinely is running, and deleting the lock in that moment is the one way to turn a harmless message into a broken install. So the order below matters: confirm first, then clear. Everything here was checked against WordPress 7.1 on PHP 8.3.

What “another update is currently in progress” actually means

The message you see on Dashboard → Updates is short and gives you nothing to work with:

Another update is currently in progress.

That string comes from the core upgrader, not from a plugin. Before WordPress starts a core update it tries to take a lock, and the lock is nothing more exotic than an option row: core_updater.lock, whose value is the Unix timestamp of the moment the update began. It is written with autoload off, which is why you will never see it in any admin screen and why plugin scanners tend to miss it.

When the update finishes — successfully or with an error it can report — core releases the lock and deletes the row. That is the whole mechanism, and it gives you your diagnosis for free: if the row still exists, the update process stopped without ever getting to its own cleanup code. PHP hit its execution limit, memory ran out, the host killed the worker, or the connection dropped while files were being unpacked.

Core asks for the core-update lock with a fifteen-minute expiry. Once the timestamp in that row is more than fifteen minutes old, the next update attempt treats the lock as abandoned, clears it, and takes a fresh one. This is why the folk advice to “just wait fifteen minutes” genuinely works, and why it is the safest first move rather than a fob-off.

Do not delete the lock in the first few minutes. If an update really is unpacking core files and you clear the lock and start a second one, two processes write into wp-admin and wp-includes at the same time. What you get is a half-old, half-new install — the failure mode that produces white screens and fatal errors on files that look perfectly normal. Wait, confirm, then clear. And take a database backup before you touch wp_options at all: wp db export pre-lock-fix.sql.

Check this before you fix anything

A surprising share of these reports are not a problem at all. The update completed, the browser tab died or was closed before the success screen rendered, and the retry ran inside the fifteen-minute window. Thirty seconds of checking saves you from fixing something that already works:

# What version is actually installed right now?
wp core version

# Is the lock there, and how old is it?
wp option get core_updater.lock

# Turn that timestamp into something readable
wp eval 'echo gmdate( "Y-m-d H:i:s", (int) get_option( "core_updater.lock" ) ), " UTC", PHP_EOL;'

If wp core version already reports the version you were updating to, you are done — close the tab and let the lock expire on its own. If wp option get returns Could not get option, there is no lock and your message is coming from somewhere else; jump to the .maintenance file and background-updater sections below.

No SSH access? Check the version at Dashboard → Updates (the current version is printed at the top of that screen) or in Tools → Site Health → Info → WordPress. The Site Health screens are worth knowing your way around for exactly this kind of question.

The causes, in the order they are usually to blame

CauseHow you confirm itFix
1. An update really is running — another tab, another admin, or you double-clickedThe lock timestamp is less than a couple of minutes oldWait. Do nothing else.
2. A previous update died mid-run (PHP timeout, memory limit, dropped connection, host killed the worker)Lock timestamp is old but the message persists; PHP error log shows a fatal or a timeout at the matching minuteWait 15 minutes, or delete core_updater.lock
3. A background automatic update is in flightwp option get auto_updater.lock returns a timestampWait, then delete auto_updater.lock if it is stale
4. A leftover .maintenance fileThe front end says “Briefly unavailable for scheduled maintenance”wp maintenance-mode deactivate, or delete the file
5. A persistent object cache is serving the deleted lockYou removed the row via SQL and the message survivedwp cache flush
6. Disk full or wrong file ownershipEvery retry fails at the same point and re-creates the lockFree space, fix ownership, then retry
7. Two installs sharing one database (a staging clone that was never re-pointed)Both sites show the message at onceGive staging its own database

Cause 2 is the one you will hit most often on shared hosting, and it is worth understanding why. Unpacking and copying the WordPress core files is one long PHP request. If max_execution_time is 30 seconds and the download plus copy takes 40, the request is terminated in the middle of the job. The lock was written; the code that would have removed it never ran.

Fix it with WP-CLI

With SSH, this is a two-command job. Run these from your WordPress root, and only once you have confirmed from the timestamp that the lock is stale:

# 1. See every lock row at once (--search accepts * as a wildcard)
wp option list --search='*.lock'

# 2. Remove the stale core update lock
wp option delete core_updater.lock

# 3. If the automatic updater left one behind too
wp option delete auto_updater.lock

# 4. Only if you run Redis or Memcached
wp cache flush

# 5. Retry the update from the command line, where you can read the error
wp core update

Step 5 is the part people skip, and it is the most useful command in the list. Running the update through WP-CLI takes the browser and its request timeout out of the picture entirely, and when it fails it prints the actual reason — a permissions error, no space left on device, a failed download — instead of a generic admin notice. If the update succeeds here, finish the job properly:

# Apply any pending database schema changes
wp core update-db

# Confirm every core file matches the official release
wp core verify-checksums

wp core verify-checksums earns its place after any interrupted update. It compares every core file against the checksums WordPress.org publishes for your version, so it catches exactly the damage a half-finished update leaves behind. A clean run means core is intact. If it lists modified files, re-run wp core update --force to lay the release down again from scratch.

No SSH? Clear the lock from the database

There is no admin screen for deleting an option, so on a shared host you go through phpMyAdmin or Adminer in your hosting panel. Take a database export first — your panel’s Export tab is fine.

Open the SQL tab and look before you delete, so you can see whether the lock is genuinely old:

SELECT option_name, option_value, FROM_UNIXTIME(option_value) AS started
FROM wp_options
WHERE option_name IN ('core_updater.lock', 'auto_updater.lock');

If started is more than fifteen minutes ago, remove the row:

DELETE FROM wp_options
WHERE option_name IN ('core_updater.lock', 'auto_updater.lock');

Check your table prefix. wp_options is only the default. Plenty of installs use something like wp7x2_options, and the prefix is set in wp-config.php on the line beginning $table_prefix. Run the query against the wrong table and you will get an error rather than damage — but you will also still have the lock. Match the WHERE option_name clause exactly as written, and never run a DELETE against wp_options without one.

The sibling error: “Briefly unavailable for scheduled maintenance”

These two get reported together often enough to be worth separating properly, because they are different mechanisms with different fixes.

Before it touches any files, the updater writes a file called .maintenance into your WordPress root. Its presence is what makes the front end serve Briefly unavailable for scheduled maintenance. Check back in a minute. to visitors. Core deletes it when the update ends, so if it survives, the same interrupted-update story applies.

  • Symptom is only in the admin, on the Updates screen → it is the option row. Clear core_updater.lock.
  • Visitors see a maintenance message → it is the file. Delete .maintenance from the root over SFTP or your file manager. It is a dot-file, so switch on hidden files if you cannot see it.
  • Both at once → an update died with both in place. Clear both, then run wp core verify-checksums before you trust the install.

From the command line there is a dedicated command for the file, documented in the WP-CLI maintenance-mode reference:

wp maintenance-mode status
wp maintenance-mode deactivate

When it is the background updater, not you

If the message appears when you have not clicked anything, the automatic updater is the likely culprit. It runs on the same schedule machinery as everything else in WordPress, takes its own lock under the name auto_updater.lock, and holds it for up to an hour by default rather than fifteen minutes. So an automatic minor release or a plugin auto-update that stalls can block your manual update for considerably longer.

Two things follow from that. First, check both lock rows, not just the core one — the query above covers them together. Second, if the same block keeps recurring on a schedule, the underlying problem is often that the queue itself is unhealthy, which is the same territory as a missed schedule error and a jammed WP-Cron queue. A site where cron half-runs and dies will produce stale locks over and over.

Stop it happening again

Clearing the lock treats the symptom. The update died for a reason, and unless you deal with that, the next one will die too.

  • Read the PHP error log for the exact minute the lock was written. You now have that timestamp, which makes the log searchable instead of a haystack. A Maximum execution time exceeded or Allowed memory size exhausted line names your problem outright.
  • Give PHP enough room. Updates want a memory limit of at least 256M and an execution time above 60 seconds. Both are hosting settings, and an install still running an old PHP build is worth checking and updating carefully — cramped limits cause several unrelated-looking failures at once.
  • Check free disk space. df -h over SSH, or the usage figure in your hosting panel. An update needs room for the download, the unpacked copy and the old files simultaneously. A full disk fails silently and looks exactly like a timeout.
  • Update from WP-CLI on anything important. No browser tab to lose, no request timeout, and real error messages.
  • Do not click Update twice. The progress feedback is thin and the temptation is real, but a second click on a slow host is one of the easiest ways to create this exact situation.
  • Rehearse major updates on staging. The same discipline that applies to updating plugins without breaking your site applies to core, and afterwards it pays to test the site deliberately rather than glancing at the homepage.

One more pattern worth naming: if updates on this site are consistently slow enough to time out, the update is not really your problem. A sluggish backend that struggles with any long request usually has a cause you can find, and diagnosing a slow admin dashboard tends to fix the update failures as a side effect.

Frequently asked questions

Is it safe to delete core_updater.lock?

Yes, provided no update is actually running. The row is a coordination flag, not data — it holds a timestamp and nothing else, and WordPress recreates it the next time an update starts. Nothing on your site references it. The only real risk is timing: delete it while files are genuinely being copied and you can end up with two updaters writing core at once. Check the timestamp, wait out the fifteen minutes, then delete.

How long should I actually wait?

Fifteen minutes from the timestamp in the lock row, because that is the expiry core requests for a core update. After that, the next attempt clears the abandoned lock itself and proceeds, so simply clicking Update Now again is often the entire fix. If the message survives past twenty minutes, the lock is being recreated by something — go back to causes 3, 5 and 6 in the table above.

I deleted the row but the message is still there. What now?

Almost always a persistent object cache. Redis and Memcached keep option values in memory, so core keeps reading the lock you just removed from the database. Run wp cache flush, or restart the cache service. Second possibility: you deleted from the wrong table because the install uses a non-default prefix. Third: something is recreating the lock, which means an update is being attempted and failing repeatedly — check the PHP error log rather than deleting the row again.

Do plugin and theme updates use the same lock?

Manual plugin and theme updates from the dashboard do not take the core update lock, so this message pointing at a plugin update is unusual. Automatic background updates are the exception — those run through the automatic updater and hold auto_updater.lock, which can block a manual core update. If a specific plugin update is what fails, that is a different problem, and it is worth isolating the conflict methodically instead.

Could a security plugin or firewall be causing this?

Indirectly, yes. Updates need an outbound HTTPS request to WordPress.org to fetch the release. If a firewall, a locked-down host or a broken DNS resolver blocks that, the update starts, writes the lock, fails to download and dies — leaving the message behind. Tools → Site Health reports whether your install can reach WordPress.org, which is the quickest way to rule this in or out.

Should I install a plugin to fix this?

No. This is one option row and, occasionally, one file. Installing a plugin to delete a row you can delete in one command adds code you then have to maintain, and any plugin that clears the lock automatically will happily clear it while a real update is in progress. Use WP-CLI if you have it and phpMyAdmin if you do not.

The short version

Run wp core version first — the update may already have succeeded. If it has not, read the timestamp with wp option get core_updater.lock, and if it is more than fifteen minutes old run wp option delete core_updater.lock, then retry with wp core update so you can see any real error. Delete .maintenance from the root if visitors are seeing a maintenance page, flush the object cache if you removed the row via SQL, and finish with wp core verify-checksums to prove core is intact. Then go and find out why the first attempt died, because a stale lock is a symptom, not a cause.

Leave a Reply to This Post