TopSyde
Get your free site auditStart Risk-Free

Fix WordPress 'Briefly Unavailable for Scheduled Maintenance'

WordPress stuck in maintenance mode? Learn exactly how to remove the .maintenance file, why it happens, and how to prevent it—including edge cases and server timeouts.

Marcus Webb

Marcus Webb

DevOps & Security Lead

··12 min read

Last updated: July 21, 2026

WordPress admin dashboard showing a stuck maintenance mode error message on a white screen

WordPress gets stuck in maintenance mode when an update process is interrupted before WordPress can delete the .maintenance file it creates at the start of every core, plugin, or theme update. The fix takes under two minutes: delete that file via FTP, SFTP, or your host's file manager, and your site comes back immediately.

What Actually Happens During a WordPress Update

WordPress's update routine is deliberate: it gates the entire process behind a lockout file so visitors see a controlled message instead of a half-updated site throwing PHP fatal errors. Here's the exact sequence:

  1. WordPress writes /.maintenance to the site root containing a PHP timestamp (<?php $upgrading = 1735000000; ?>)
  2. WordPress downloads the update package to a temporary directory
  3. The package is extracted and files are moved into place
  4. The database is updated if required
  5. WordPress deletes /.maintenance and redirects back to normal operation

The maintenance.php drop-in (or the built-in fallback in wp-includes/functions.php) checks for this file on every request. If the file exists and the timestamp is less than 10 minutes old, it serves the maintenance screen. If the file is older than 10 minutes, WordPress actually ignores it automatically—which is why some sites recover on their own and others don't.

The 10-minute TTL is intentional. The problem is that the file never gets deleted when the update process crashes, so the timestamp stays fresh on the next request, starting the clock over. That is why waiting it out doesn't work.

How to Fix It: Delete the .maintenance File

The fix is the same regardless of whether the stuck update was a core release, a plugin, or a theme.

Method 1: FTP or SFTP (most reliable)

Connect to your server with an FTP client like FileZilla or Transmit. Navigate to your WordPress root—the same directory that contains wp-config.php, wp-admin/, and wp-content/. You are looking for a file named .maintenance. Because the filename starts with a dot, it is hidden by default on most systems.

In FileZilla: Server → Force showing hidden files. In Transmit: View → Show Hidden Files. Once visible, select .maintenance and delete it. Your site is live the moment the file is gone.

Method 2: cPanel or Plesk File Manager

Log in to your hosting control panel and open File Manager. Navigate to public_html (or your WordPress root if it differs). Enable hidden files—cPanel has a "Settings" button in the top-right where you toggle "Show Hidden Files (dotfiles)." Delete .maintenance. Done.

Method 3: WP-CLI (fastest for SSH access)

wp eval 'if (file_exists(ABSPATH . ".maintenance")) { unlink(ABSPATH . ".maintenance"); echo "Deleted."; } else { echo "File not found."; }'

Or more directly:

rm /var/www/html/.maintenance

Replace /var/www/html/ with your actual WordPress root path.

Method 4: PHP script (use with caution)

If you have no FTP or SSH access and your host's file manager is inaccessible, you can upload a temporary PHP file to your server root via any available file upload mechanism:

<?php
$file = dirname(__FILE__) . '/.maintenance';
if (file_exists($file)) {
    unlink($file);
    echo 'Maintenance file removed.';
} else {
    echo 'Maintenance file not found.';
}

Upload as fix-maintenance.php, visit https://yourdomain.com/fix-maintenance.php, then immediately delete the file. Leaving executable PHP scripts exposed in your web root is a security risk.

Why Did the Update Fail in the First Place?

Deleting the file gets your site back online, but it does not fix what caused the crash. Check your PHP error log (wp-content/debug.log if WP_DEBUG_LOG is enabled, or the server-level error log) before you try the update again.

PHP execution timeout

The most common cause. Shared and entry-level hosting environments often set max_execution_time to 30–60 seconds. Downloading a large plugin archive, extracting it, and moving files can easily exceed that. The update process dies mid-operation, .maintenance stays.

Fix: Increase max_execution_time in php.ini or .htaccess:

php_value max_execution_time 300

Or via wp-config.php:

@ini_set('max_execution_time', 300);

Memory exhaustion

If WordPress runs out of memory mid-update, PHP throws a fatal error and the process terminates. Check your log for Allowed memory size of X bytes exhausted.

Fix: In wp-config.php:

define('WP_MEMORY_LIMIT', '256M');
define('WP_MAX_MEMORY_LIMIT', '512M');

WP_MAX_MEMORY_LIMIT specifically covers admin and update operations.

Failed package download

WordPress fetches update packages from downloads.wordpress.org. If that request times out or the server blocks outbound HTTP, the download fails. Check wp-admin/update-core.php manually—if it reports a download error rather than hanging, this is your issue.

Fix: Verify outbound HTTP connectivity from your server. Some hardened hosting environments block outbound requests that aren't on an allowlist. Contact your host if your server cannot reach downloads.wordpress.org.

Concurrent update attempts

Multiple admins triggering updates simultaneously, or an automated updater (ManageWP, MainWP, a cron job) running at the same time as a manual update, can create race conditions. The second update process reads the .maintenance file left by the first and may exit immediately—leaving both processes in an undefined state.

Fix: Use a single update path. If you use an automated update plugin, disable manual updates or vice versa. Configure automated updates to run during low-traffic hours.

File permission errors

If WordPress cannot write to a directory during extraction, the update aborts. Check for directories set to 444 or files owned by a different user than your PHP process.

find /var/www/html/wp-content/plugins -not -writable -type d

Correct permissions: directories at 755, files at 644, owned by your web server user.

Checking What Happened to the Update Itself

After you restore access, you need to verify the update state. A partially applied update is worse than no update at all.

Check the plugin/theme version

Go to Plugins → Installed Plugins or Appearance → Themes and compare the version shown against the current version in the WordPress plugin directory. If they match, the update completed before the process crashed. If they don't, the update is in an unknown state.

For a partially updated plugin, the safest recovery is to deactivate it, manually delete its directory via FTP, and reinstall from the plugin directory. Do not just re-run the update on a partially extracted plugin—it will overwrite some but not all files depending on where the extraction failed.

For a partially updated WordPress core, use WP-CLI:

wp core verify-checksums

This compares your core files against WordPress.org's checksums for your version. Any mismatched or missing files are reported. Follow up with:

wp core update --force

to re-download and apply the full package.

Review update logs

WordPress 6.6+ logs update activity to the database. You can retrieve recent events:

wp option get auto_updater.lock
wp option get update_core

The auto_updater.lock transient in particular will tell you if an automated update process died while holding a lock—which can prevent future updates from running until the transient expires (typically 15 minutes).

Comparison: Recovery Options by Access Level

Access AvailableBest MethodTime to FixNotes
SSH / WP-CLIWP-CLI unlink or rm~30 secondsFastest; also lets you run wp core verify-checksums immediately
SFTP / FTPFileZilla / Transmit1–2 minutesEnable hidden files display first
cPanel File ManagerBuilt-in file manager1–3 minutesToggle dotfiles in Settings
Plesk File ManagerBuilt-in file manager1–3 minutesIdentical to cPanel flow
Hosting dashboard onlyPHP script upload3–5 minutesDelete the PHP file immediately after
No file access at allContact host supportVariesShould be last resort; any host worth using gives you SFTP

How to Prevent WordPress Maintenance Mode From Getting Stuck

Prevention is straightforward once you understand that the problem is almost always a resource constraint or a process interruption.

Increase PHP limits before updating. Set max_execution_time to at least 300 seconds and memory_limit to at least 256M. On managed hosts this is typically handled for you. On shared hosting, do it via .htaccess or php.ini if your plan allows.

Update one item at a time during initial diagnosis. If you have 30 plugins queued for updates and you click "Update All," a timeout on plugin 12 leaves you unsure which plugin failed and in what state. Update core first, then plugins individually until you understand your server's performance envelope. This is especially relevant if you haven't done a thorough WordPress plugin audit to identify which plugins are heavy or poorly maintained.

Use a staging environment. Test updates in staging before production. A failed update in staging tells you about resource constraints without any user impact. Staging also catches the increasingly common problem of a new plugin version that is technically installed correctly but breaks your site's frontend—which the .maintenance cleanup cannot help with.

Keep an eye on the plugin directory. Plugins that have been removed from the WordPress directory often have broken update endpoints. Attempting to update a delisted plugin can hang the update process indefinitely. Our post on what happens when a plugin is removed from the WordPress directory covers how to identify and handle these cases.

Automate with guardrails, not blindly. Automated updates are good practice—according to Sucuri's 2024 Hacked Website Report, outdated plugins and themes account for 61% of known-vulnerability WordPress compromises. But automated updates without staging, version pinning, or rollback capability are how a smooth automated system turns into a 3 AM emergency.

How Managed Hosting Handles This Automatically

On properly configured managed WordPress hosting, the conditions that cause a stuck .maintenance file are largely engineered away before you encounter them.

PHP execution time limits on managed platforms are set at 300+ seconds specifically because update operations need headroom. Memory limits are pre-configured at 256M or higher. Update processes run in isolated contexts so a timeout on one plugin does not corrupt the overall operation. Many managed hosts also run updates through queued background jobs with retry logic, not inline PHP execution tied to a browser request.

TopSyde's managed WordPress hosting—available from $89/mo per site—manages core and plugin update scheduling with pre-update snapshots so that a bad update is a rollback, not a recovery operation. TopSyde Sentinel monitors the update process itself and flags when an update terminates abnormally, alerting the team within under 2 hours during business hours rather than waiting for a client to notice their site is down.

If you're evaluating whether managed hosting makes sense for your workload, the honest ROI breakdown in our managed hosting cost analysis walks through exactly when the automation premium pays for itself versus when DIY maintenance is fine.

For agencies managing multiple client sites, the maintenance mode problem is multiplied by your client count. The managed WordPress hosting workflow for agencies covers how update orchestration across a fleet is handled without requiring per-site babysitting.

Frequently Asked Questions

Why does WordPress show maintenance mode for more than 10 minutes if it's supposed to auto-clear?

The 10-minute timeout only triggers when WordPress can evaluate the timestamp in the .maintenance file. If the file is malformed (zero bytes or missing the PHP timestamp) due to a crash mid-write, WordPress may not be able to parse it correctly, meaning the auto-expiry logic never fires. Always inspect the file contents if the 10-minute rule seems to not be working.

Can I prevent the maintenance screen from showing at all during updates?

Not without removing the maintenance gate entirely, which is not advisable. You can customize the message shown to visitors by adding a maintenance.php file to your wp-content/ directory—WordPress will use that as the template instead of its default screen. This lets you show a branded message with your contact info, but the gate itself should stay in place; it exists to protect users from seeing a partially updated site.

Is it safe to run updates again immediately after deleting the .maintenance file?

Only if you have verified the previous update did not partially apply. Run wp core verify-checksums for core updates, and manually confirm the installed version for any plugin that was updating when the process failed. If a plugin is in a partially updated state, reinstall it cleanly before retrying. Attempting to update a partially extracted plugin file set can result in conflicts between old and new file versions that produce PHP fatal errors unrelated to the .maintenance file.

Does deleting the .maintenance file fix a broken update, or just the maintenance screen?

It only fixes the maintenance screen. The underlying update may be complete, partial, or untouched—deleting .maintenance has no effect on that. Think of the file as a door lock: removing it lets visitors in, but it says nothing about whether the room behind the door is tidy.

Will this problem happen again on the same plugin?

Possibly, if the root cause was a resource limit that you haven't addressed. A plugin that requires more memory or execution time than your environment provides will fail every time on that same step. Identify the constraint from your error log, fix it, then re-run the update. If you continue to see failures on the same plugin without a clear resource error, check whether that plugin has been flagged for removal from the WordPress directory or has open, unresolved GitHub issues related to the update process.

Marcus Webb
Marcus Webb

DevOps & Security Lead

12+ years DevOps, Linux & cloud infrastructure certified

Marcus leads infrastructure and security at TopSyde, managing the server fleet and AI monitoring systems that keep client sites fast and protected. Former sysadmin turned WordPress hosting specialist.

Related Articles

View all →

TopSyde Sentinel

Hacked — or worried you're next?

Malware cleanup is free when you switch to TopSyde. After that it's simply handled — Sentinel scans daily and removes anything it finds automatically. No cleanup bills, no security consultant, ever. All included in flat $89/mo hosting.

Flat $89/mo per site · Free migration · 30-day money-back guarantee