WordPress Stuck in Maintenance Mode? How to Fix It (Tested)

Reviewed by Mohammad HumzaPublished 14 min readSecurity & Maintenance
A traffic cone and wrench on a laptop with a blank screen, illustrating a WordPress site stuck in maintenance mode

If your site shows “Briefly unavailable for scheduled maintenance. Check back in a minute.”, delete the hidden .maintenance file in your WordPress root folder, the one that holds wp-config.php, and the site comes back on the next page load. That one file is the whole switch. If you find WordPress stuck in maintenance mode for much longer than 10 minutes, look past that file too, because current WordPress ignores its own .maintenance file once it is 10 minutes old.

I tested all of this on a local WordPress 7.1.2 site: what visitors and the admin get while the file exists, the exact second the 10-minute rule lets the site back in, what a custom maintenance page changes, and the WP-CLI commands.

What is maintenance mode on WordPress?

WordPress maintenance mode is a built-in lock that core switches on while it replaces files during a core update or an update to an active plugin or theme, so nobody loads a half-copied plugin. While it is on, every request gets a plain white page titled “Maintenance” with one line: “Briefly unavailable for scheduled maintenance. Check back in a minute.” The server sends HTTP 503, which means “temporarily unavailable”, and a Retry-After: 600 header.

In my test the front end, /wp-admin/, /wp-login.php and /wp-json/ all returned that same page. The dashboard sits behind the same 503, so the fix has to happen in the files.

Maintenance mode plugins are a different thing. SeedProd and similar plugins show a designed page with your logo, often let logged-in admins through, and are switched on and off in the plugin’s own settings. If you see a branded page, deleting .maintenance will not help. Turn the mode off in the plugin, or, without wp-admin, rename that plugin’s folder in wp-content/plugins over SFTP so WordPress deactivates it.

How does WordPress maintenance mode work?

Two short functions in wp-includes/load.php do all of it (the WordPress 7.1 source on GitHub matches the 7.1.2 install I tested). When an update starts, the upgrader writes .maintenance to the root folder. The one WP-CLI wrote for me was 33 bytes:

<?php $upgrading = 1791972622; ?>

That number is a Unix timestamp: the second the update began. On every request, wp-settings.php calls wp_maintenance() before the database connection and before any plugin or theme loads. It asks wp_is_maintenance_mode(), which checks:

  1. Is there a .maintenance file? If not, the site runs normally.
  2. Is time() - $upgrading 600 seconds or more? Then maintenance is over. The core comment: “If the $upgrading timestamp is older than 10 minutes, consider maintenance over.”
  3. Does the enable_maintenance_mode filter return false? WP-CLI hooks it that way, which is why WP-CLI kept working on my site while browsers got the 503.

If the site is in maintenance, wp_maintenance() looks for wp-content/maintenance.php. If that file exists, WordPress loads it and stops. If not, it sends Retry-After: 600 and calls wp_die() with the standard message and status 503. The wp_is_maintenance_mode() reference puts the rule in one line: if the file “was created less than 10 minutes ago, WordPress is in maintenance mode.”

Why is WordPress stuck in maintenance mode?

You end up with WordPress stuck in maintenance mode when the request running the update stops before it reaches the line that deletes .maintenance. The file is written at the start and removed at the end, and nothing in between cleans up after a crash.

Bulk updates widen the window. When you tick several plugins and click Update, bulk_upgrade() turns maintenance mode on once (if at least one of them is active), updates every plugin in a loop, and turns it off after the last one. Ten updates share one lock and one long PHP request, and a fatal error on plugin seven leaves the file behind.

Things that stop that request partway:

  • Closing the tab or losing the connection. PHP’s manual says the default is “for your script to be aborted when the remote client disconnects.”
  • A timeout. WordPress asks PHP for 300 more seconds per package while it unpacks and copies files, but the request can still be cut off before the end.
  • A fatal error or running out of memory while a new plugin version loads. My guide to increasing the WordPress memory limit covers the memory side.
  • Automatic background updates. The automatic updater uses maintenance mode for plugin, theme and core updates too, and switches it on again while it checks for fatal errors afterwards. This can happen overnight with nobody clicking anything.
Cause What you see Fix
Update interrupted (tab closed, timeout, crash) Plain “Briefly unavailable” page on every URL, HTTP 503 Delete .maintenance, then re-run the update one plugin at a time
Update still running Same page, for a minute or two Wait. Core ignores the file after 10 minutes anyway
A .maintenance file that never expires Plain page for hours or days Delete the file and read what is in it (see below)
Maintenance mode plugin left on Branded or “coming soon” page, admins may still get in Turn the mode off in the plugin, or rename its folder
Custom wp-content/maintenance.php Your own design instead of the WordPress line Delete .maintenance; make the drop-in send a 503
Update finished but broke a plugin “There has been a critical error” or a blank page after the file is gone Treat it as a fatal error, not maintenance mode

That last row is a different problem: the update finished copying a plugin that crashes. My guide to the WordPress white screen of death covers finding and switching off that plugin.

How do you turn off maintenance mode in WordPress?

Delete the .maintenance file. When I find WordPress stuck in maintenance mode, I work in this order.

1. Give a running update a minute

If you clicked Update moments ago, the file may be doing its job. Core’s own timer is 10 minutes. If the page has been up longer than that, or you know the tab closed, move on.

2. Delete the .maintenance file

Open your host’s file manager or connect over SFTP and go to the folder that contains wp-admin, wp-content, wp-includes and wp-config.php. The file name starts with a dot, so turn on “show hidden files” if you do not see it. Delete it and reload the site. With SSH, run rm .maintenance from that folder.

WP-CLI’s wp maintenance-mode deactivate also worked in my test, with one catch: it applies the same 10-minute rule as core. Pointed at a 700-second-old file, it answered “Error: Maintenance mode already deactivated.” and left the file in place. That file is harmless, but rm is the reliable way to remove it.

3. Check whether the update actually finished

Deleting the file removes the lock, not the cause. Open Dashboard > Updates: any plugin still waiting for its update did not finish, so update it on its own, then do the rest one at a time.

4. Clear caches if a visitor still sees the page

WordPress sends its 503 page with Cache-Control: no-cache, must-revalidate, max-age=0, no-store, private, so a well-behaved cache should not keep it. If a private window loads the site fine, it is your browser. If everyone still sees it, check your host’s cache or CDN.

5. Skip the wp-activate.php trick

Some guides say to edit wp-activate.php and change define( 'WP_INSTALLING', true ) to false. That file is the multisite account activation page, and the constant only applies to requests for that one URL. In my test it was the only address that skipped maintenance mode: /wp-activate.php redirected while the home page still returned 503. Editing it fixes nothing for the rest of the site.

What happened when I left WordPress stuck in maintenance mode on purpose

I ran these tests on 2026-10-14 on a local WordPress 7.1.2 site (PHP 8.2.12, SQLite, Twenty Twenty-Five) served by PHP’s built-in web server, checking each response with curl. I wrote .maintenance by hand to control its timestamp and used WP-CLI 2.12.0 for the command tests. I backed up the config and database first and restored both afterwards (checksums matched).

Test Result
.maintenance with the current time HTTP 503 and Retry-After: 600 on the home page, a post URL, wp-admin, wp-login.php and wp-json; 2,500 bytes, “Briefly unavailable for scheduled maintenance.”
Timestamp 590 seconds old Still 503
Timestamp 700 seconds old HTTP 200, full home page (202,715 bytes), with the file still there
File left to age on its own 503 at 595 seconds, 200 at 601 seconds
$upgrading = time(); typed into the file 503 at all 13 checks, from 0 to 723 seconds after I created the file; 200 once I deleted it
wp-content/maintenance.php with plain HTML My page on every URL, but HTTP 200 and no Retry-After header
Same page with two header lines added HTTP 503 and Retry-After: 600
Request to /wp-activate.php during maintenance 302 redirect, not 503
Deleted .maintenance HTTP 200 on the next request
wp maintenance-mode activate / deactivate Activate wrote the file shown above (503); deactivate deleted it (200)
Home page status vs age of the .maintenance file 0 2 4 6 8 10 12 Minutes since the timestamp in the file 10 min cutoff in core Updater-style timestamp 503 200 $upgrading = time(); 503 at every check, 0 to 723 seconds 503 maintenance page 200, site back
With a fixed timestamp, as the updater writes it, the site let itself out between 595 and 601 seconds. A file using time() never expired. Source: my tests on WordPress 7.1.2 and PHP 8.2.12, 2026-10-14.

The 10-minute rule is real, and it is exact. I set the file’s timestamp to 570 seconds ago and requested the home page every few seconds. The site served 503 up to 595 seconds and 200 from 601 seconds, without me touching the file. So a core lock left by a failed update clears itself in at most 10 minutes. If you have had WordPress stuck in maintenance mode for an hour, something other than a normal update wrote the file, or the page is not coming from core.

A hand-made file can lock the site for good. Tutorials that show how to turn on maintenance mode manually often write $upgrading = time(); into the file. Because WordPress runs that file on every request, time() is always “now” and the 10-minute rule never fires. I left one in place for 12 minutes and the site never came back on its own: it returned 503 at every check, including 723 seconds after the file was created. If you find that line in a stuck site’s .maintenance file, it was written by a person or a tool, not by the WordPress updater, which always writes a fixed number.

A custom maintenance page can send the wrong status. WordPress loads wp-content/maintenance.php before it sends any header or loads its helper functions (status_header() did not exist yet), so my plain HTML page went out as HTTP 200. Google says 5xx errors make its crawlers slow down while it keeps indexed URLs for a while, so a short outage should be a 503. Start the file with these lines:

<?php
http_response_code( 503 );
header( 'Retry-After: 600' );
?>

How long does WordPress maintenance take?

Only while files are being replaced, and core caps it at 10 minutes: after 600 seconds WordPress serves pages again even if the file is still there. I did not time live updates for this post, so that ceiling is the only number I will give you. Do not leave a stuck site for days: Google says URLs that keep returning server errors are eventually dropped from its index.

How do you stop it happening again?

WordPress stuck in maintenance mode is nearly always a side effect of how updates are run, so prevention is simple:

  • Update fewer plugins at once. A bulk update holds one lock across the whole batch. Two or three at a time keeps each request short and shows which one failed.
  • Test big updates on a staging copy first, especially WooCommerce, page builders and anything that touches checkout or forms.
  • Take an off-site backup before you update. Restoring is the fallback when an update leaves a plugin half copied.
  • Leave the update screen open until WordPress says it is finished.
  • Give PHP enough memory so a large plugin does not crash mid-update.

These are the same habits that keep a site secure, which my guide to securing a WordPress site covers in more depth. If you would rather not run updates yourself, tested one-at-a-time updates, off-site backups and uptime checks are what my WordPress maintenance service covers, and my breakdown of WordPress maintenance costs shows what that kind of upkeep should cost.

If the site comes back from maintenance but the browser then says “redirected you too many times”, read the chain and fix the loop with my guide to too many redirects in WordPress.

Frequently asked questions

How do I turn off maintenance mode in WordPress?

Delete the hidden .maintenance file from your WordPress root folder, the one that contains wp-config.php, using your host’s file manager, SFTP or SSH. The site loads again on the next request. With WP-CLI, run wp maintenance-mode deactivate. If the page is branded, it comes from a maintenance mode plugin, so switch the mode off in that plugin’s settings instead.

How long can WordPress stay in maintenance mode?

Only as long as the update needs to replace files, and never more than 10 minutes for a lock written by the WordPress updater. Core ignores the .maintenance file once its timestamp is 600 seconds old. In my test on WordPress 7.1.2 the site switched from 503 back to normal between 595 and 601 seconds without anyone touching it.

What is maintenance mode on WordPress?

It is a temporary lock WordPress switches on during plugin, theme and core updates. Core creates a .maintenance file in the root folder, and while it exists every page, including wp-admin, returns HTTP 503 with the message “Briefly unavailable for scheduled maintenance. Check back in a minute.” WordPress deletes the file when the update finishes.

Why is WordPress stuck in maintenance mode after I deleted the .maintenance file?

Usually because the page is not coming from core. A maintenance or coming-soon plugin, a theme setting or a cached copy can all show a similar page. Check for a branded design, turn off any maintenance plugin, and test in a private window. If the file reappears, an automatic update or another tool is still writing it.

Does WordPress maintenance mode hurt SEO?

Not for a few minutes. Core sends HTTP 503 with a Retry-After header, which tells search engines the outage is temporary. Google says 5xx errors make its crawlers slow down and that indexed URLs are kept for a while but eventually dropped if the errors continue, so fix a stuck site quickly rather than leaving it for days.

Sources

  • wp_is_maintenance_mode() and wp_maintenance(), WordPress Code Reference, developer.wordpress.org and developer.wordpress.org, retrieved 2026-10-14.
  • WordPress 7.1 source, wp-includes/load.php, github.com/WordPress/wordpress-develop, retrieved 2026-10-14, and the 7.1.2 upgrader files, read 2026-10-14.
  • wp maintenance-mode, WP-CLI Commands, developer.wordpress.org, retrieved 2026-10-14, and the command’s source in WP-CLI 2.12.0.
  • How HTTP status codes affect Google’s crawlers, Google for Developers, developers.google.com, retrieved 2026-10-14.
  • Retry-After header, MDN Web Docs, developer.mozilla.org, retrieved 2026-10-14.
  • Connection handling, PHP Manual, php.net, retrieved 2026-10-14.
  • Tests on a local WordPress 7.1.2 install with PHP 8.2.12 and WP-CLI 2.12.0, by Mohammad Humza, 2026-10-14.

Share this article

Copied

Start a project

Working on something like this? Send a line and get a written quote within one business day.