The fix, in one minute
Delete the file called .maintenance from your WordPress root, the directory containing wp-config.php and wp-admin. The site comes back as soon as it is gone.
# over SSH, from the WordPress root
ls -la .maintenance
rm .maintenance
Over FTP or in a host file manager, you must turn on showing hidden files first, because a leading dot hides it by default. In cPanel's File Manager it is Settings, then Show Hidden Files. In FileZilla it is Server, then Force showing hidden files.
That is the whole fix for the symptom. Now the part that actually matters.
Why it happened
Before an update, WordPress writes .maintenance containing a timestamp. While it exists and is recent, every front-end request gets the maintenance notice instead of your site. When the update finishes, WordPress deletes it.
If the update never finishes, nothing deletes it. The usual interruptions:
- PHP timed out partway through, which is the most common on shared hosting and most likely when updating many plugins at once
- Memory limit hit while unpacking
- The browser tab was closed or the connection dropped during a bulk update
- A file could not be written because of permissions or ownership
- The host killed the process for exceeding a resource limit
Note what all of these have in common: the update stopped in the middle. That is why deleting the file is the start of the job and not the end.
The important part: what the interrupted update left behind
The maintenance notice was a symptom. Something was being upgraded when the process died, and it is now in an unknown state: new files partly copied, or files updated while the database migration never ran.
Work through this once the site is back.
- Find out what was mid-update. Check the updates screen, and your error log around the time it stopped.
- Reinstall whatever it was, cleanly. Do not assume partial files are fine.
- Let WordPress finish any database work. Visiting
/wp-admin/upgrade.phpprompts core to complete a pending database update. - Check the site properly, especially anything that plugin touches: checkout, forms, bookings.
- Then update the rest one at a time, so the next failure is immediately attributable.
# what still needs updating
wp core check-update
wp plugin list --update=available --fields=name,version,update_version
# force a clean reinstall of the one that was interrupted
wp plugin install the-plugin-name --force
# confirm core files match the official release
wp core verify-checksums
That last command is the quickest way to know whether an interrupted core update left damaged files. Anything reported as not verifying should be fixed with wp core download --force --skip-content, which overwrites core and leaves your content alone.
If a plugin is now throwing a fatal error, the site may be white rather than in maintenance mode, which is a different problem with a different fix. Read the error log first; it names the file.
Preventing it
This is almost entirely avoidable, and the measures are cheap.
| Measure | Why it works |
|---|---|
| Update in batches of three or four | Each batch finishes inside the time limit. Bulk-updating twenty is the classic trigger |
| Keep the tab open until it completes | The request is doing the work; closing it can end the process |
| Update core on its own | It is the longest operation and the worst one to interrupt |
| Use WP-CLI where you have it | No browser request to time out, and clearer errors |
| Raise PHP time and memory limits | Removes the usual cause on shared hosting |
| Back up first | Turns a bad outcome into an inconvenience |
| Do not update right before you leave | The failure mode is a site that is down until somebody looks |
If you are on a slow shared host and see this repeatedly, the underlying issue is usually resource limits rather than WordPress. An outdated PHP version is often part of it too; see PHP end of life and your WordPress site.
If deleting the file does not fix it
Then the maintenance notice was not what was stopping the site. Three possibilities, in order of likelihood.
- A fatal error from the half-updated plugin or theme. Read the log; it names a file and a line.
- A caching layer still serving the maintenance page. Clear the page cache and any CDN, and check in a private window.
- A plugin-generated maintenance mode, which is a different mechanism from WordPress's own and is switched off in that plugin's settings.
# the usual log locations
tail -50 wp-content/debug.log
tail -50 ../logs/error_log
# if the site is white, disable plugins until it loads
wp plugin deactivate --all
wp plugin activate one-plugin-at-a-time
Deactivating all plugins is a diagnostic, not a fix. It tells you which plugin is responsible in a couple of minutes, and you reactivate the rest as you go.
If the site is down and an update has left it in a state you cannot unpick, that is worth handing over rather than experimenting on production. Tell us what you were updating when it stopped and we will get it back and tell you why it failed.