Back to tutorials
Tutorial

WordPress Stuck in Maintenance Mode Tutorial (2026): Fix .maintenance, Restore Admin Access, and Prevent Repeat Downtime

WordPress stuck in maintenance mode tutorial (2026): remove .maintenance safely, recover wp-admin, and prevent repeat downtime on VPS/cPanel.

By Anurag Singh
Updated on Sep 12, 2026
Category: Tutorial
Share article
WordPress Stuck in Maintenance Mode Tutorial (2026): Fix .maintenance, Restore Admin Access, and Prevent Repeat Downtime

That “Briefly unavailable for scheduled maintenance” screen usually traces back to one tiny file: .maintenance. WordPress creates it during updates, then removes it when everything finishes cleanly.

If an update dies mid-run, the file can stick around and your site stays “locked.” This WordPress stuck in maintenance mode tutorial walks you through clearing the lock safely, confirming what failed, and tightening your update routine so you stop doing emergency recoveries.

The process below works on a VPS (Ubuntu/Debian/AlmaLinux/Rocky) and on shared hosting/cPanel. You’ll use SSH or File Manager, run a few quick checks, and then bring plugins/themes back in a controlled way. That helps you avoid trading one outage for another.

What “maintenance mode” actually means (and why it gets stuck)

During updates, WordPress creates .maintenance in the site root (the same directory as wp-config.php). While that file exists, WordPress serves the maintenance message to visitors. On a successful update, WordPress deletes the file at the end.

  • Stuck state: the update process stops (PHP timeout, memory limit, disk full, permissions, network drop), and the file remains.
  • Common triggers on hosting: low PHP max_execution_time, aggressive security rules, exhausted inodes, or running updates directly on a busy production site.

Before you change anything: take a fast snapshot-style backup

If the update only half-applied, you want a clean way back. Back up files and database before you touch plugins or themes.

On a VPS (SSH): quick file + database backup

From your WordPress root (adjust paths as needed):

cd /var/www/example.com/public_html

tar -czf /root/example.com-wp-files-$(date +%F).tar.gz .

For the database (use your DB name/user from wp-config.php):

mysqldump -u wpuser -p wpdatabase > /root/example.com-wp-db-$(date +%F).sql

On cPanel

  • Files: cPanel → File Manager → select your WordPress directory → Compress.
  • Database: phpMyAdmin → select DB → Export (Quick is fine for most sites).

If you want a more repeatable backup workflow (and to test restores), keep this handy: rsync backup tutorial for VPS.

Step 1: confirm you’re in the correct WordPress root

Deleting the wrong .maintenance file won’t hurt anything. But it can waste time and send you in circles.

Make sure you’re in the directory that contains wp-config.php and wp-admin.

VPS/SSH check

pwd
ls -la
ls -la wp-config.php wp-admin 2>/dev/null

If those files don’t exist, you’re not in the WordPress root. Common roots include:

  • /var/www/example.com/public_html
  • /home/username/public_html
  • /home/username/domains/example.com/public_html (some panels)

Step 2: remove the .maintenance lock (the safe way)

The fastest recovery is removing .maintenance. A safer habit is renaming it first.

Renaming gives you a quick undo if you discover an update is still running.

VPS/SSH

cd /var/www/example.com/public_html

# See if it exists
ls -la .maintenance

# Safer than delete: rename
mv .maintenance .maintenance.bak-$(date +%s)

Refresh the site. If it loads, the lock-file was the entire problem.

cPanel File Manager

  1. Open File Manager and navigate to your WordPress directory.
  2. Enable Show Hidden Files (dotfiles) if needed.
  3. Find .maintenance and rename it to .maintenance.bak.

Step 3: if the site still errors, check the real failure (logs first, not guesses)

Sometimes maintenance mode is only the first symptom. If the update partially installed core/plugin/theme files, you may see a PHP fatal even after removing .maintenance.

Don’t play whack-a-mole. Read the error, then fix the actual break.

Quick diagnostics checklist

  • Does the home page show a white screen, a 500 error, or a PHP error message?
  • Can you access /wp-admin/ or does it fatal too?
  • Did the update include core, a large plugin (WooCommerce), or multiple plugins at once?

Where to look for logs (VPS)

  • Nginx: /var/log/nginx/error.log
  • Apache: /var/log/apache2/error.log (Debian/Ubuntu) or /var/log/httpd/error_log (AlmaLinux/Rocky)
  • PHP-FPM: often /var/log/php8.3-fpm.log or via pool config in /etc/php/8.3/fpm/pool.d/www.conf
# Show recent web errors
sudo tail -n 120 /var/log/nginx/error.log
sudo tail -n 120 /var/log/apache2/error.log

If your logs are huge or rotate unpredictably, set up predictable retention: Logrotate tutorial for hosting VPS.

Enable WordPress debug logging (temporary)

If server logs don’t show a clear culprit, enable WordPress debug logging briefly. Edit wp-config.php and add/adjust:

define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);

Reproduce the error once, then check:

tail -n 120 wp-content/debug.log

Disable debug again after you’ve identified the issue.

Step 4: recover wp-admin by disabling plugins (without deleting data)

If a plugin update triggered the failure, disable plugins at the filesystem level. Renaming the plugins directory makes WordPress treat everything as inactive.

This often restores wp-admin access immediately.

Disable all plugins (filesystem method)

cd /var/www/example.com/public_html/wp-content
mv plugins plugins.disabled-$(date +%F-%H%M)
mkdir plugins

Reload /wp-admin/. If it opens, you’re dealing with a plugin-level failure.

Re-enable plugins one by one

Bring plugins back gradually so you can pinpoint the offender.

ls -1 plugins.disabled-*/
  1. Move back one plugin folder.
  2. Reload the site.
  3. Repeat until the failure returns. The last plugin moved is your likely culprit.

Pitfall: Avoid “fixing” this by deleting random plugin folders. Renaming keeps the files intact for reinstall, diffing, or vendor support.

Step 5: if it’s the theme, switch to a default theme without wp-admin

A bad theme update can break the front end and, in some cases, the admin. You can force a theme switch without logging in.

The most reliable approach is updating database values. That prevents WordPress from loading a theme that isn’t usable.

Database method (phpMyAdmin or CLI)

Find your table prefix in wp-config.php (often wp_). Then update template and stylesheet in the options table to a default theme that exists (for example, twentytwentysix if installed).

SQL (adjust prefix and theme directory name):

UPDATE wp_options SET option_value='twentytwentysix' WHERE option_name IN ('template','stylesheet');

If you don’t have a default theme installed, upload one to wp-content/themes/ first.

Step 6: fix the root causes that trigger stuck maintenance mode

Removing .maintenance gets you back online. It does not prevent the next update from failing the same way.

This matters even more on WooCommerce stores under load.

Raise the limits that commonly break updates

  • PHP memory_limit: aim for 256M–512M for typical WordPress + WooCommerce stacks.
  • max_execution_time: 120–300 seconds helps with plugin updates and language packs.
  • Disk space/inodes: low disk can cause half-written files and failed extraction.

On a cPanel VPS, PHP-FPM settings are usually easier to tune and keep stable. If your WordPress sites spike CPU during admin actions, this guide is a good next step: PHP-FPM setup guide tutorial.

Check permissions (quick and safe)

Incorrect ownership can block WordPress from removing .maintenance or writing updated files.

# From the WordPress root
find . -maxdepth 2 -name '.maintenance*' -ls
ls -la .maintenance* 2>/dev/null

On many VPS setups, your web user might be www-data (Ubuntu/Debian) or apache (AlmaLinux/Rocky). Don’t blindly chown the entire tree if you host multiple sites.

Correct ownership only for the affected vhost directory.

Stop updating on a live site without a safety window

Give yourself a 10–15 minute maintenance window for updates. For stores, do it during low traffic and avoid cache purge spikes while you’re changing files.

If you want a safer workflow, use staging plus a simple “hold” page that won’t interfere with checkout flows. This tutorial supports that approach: WordPress maintenance mode tutorial.

Step 7: harden your update process (so it fails safe)

Your goal is boring updates. You want predictable results, visible output, and an easy rollback.

Use WP-CLI updates on a VPS (recommended)

WP-CLI gives you clearer output than clicking “Update” in wp-admin. Install WP-CLI (if not present) and run updates inside a screen/tmux session.

This way, a dropped SSH connection doesn’t kill the process.

# Example: update plugins with output
cd /var/www/example.com/public_html
wp plugin update --all --allow-root

Tip: If you run PHP as a non-root site user, remove --allow-root and use the correct user.

Set a real cron job and disable slow WP-Cron behavior

If WP-Cron is slow or blocked, background tasks can stack up. That can push admin requests into timeouts right when you’re trying to update.

Use a real server cron and disable the pseudo-cron.

  1. Add to wp-config.php:
define('DISABLE_WP_CRON', true);
  1. Create a system cron (example runs every 5 minutes):
*/5 * * * * /usr/bin/php -d detect_unicode=0 /var/www/example.com/public_html/wp-cron.php >/dev/null 2>&1

If scheduled posts or WooCommerce emails already misfire, troubleshoot first: WordPress cron troubleshooting tutorial.

Step 8: confirm the site is clean after recovery (fast checks)

Once the site is back, take five minutes to confirm you didn’t only unblock the homepage. Admin and checkout can still be broken.

  • Front-end: load homepage + one product/post page.
  • Admin: login, open Updates screen, check Site Health.
  • Uploads: upload a small image in Media Library.
  • Checkout (stores): add to cart and reach payment step (test mode if available).

Where HostMyCode fits: pick the hosting level that prevents repeat incidents

This outage shows up more often on servers that are resource-starved or overcrowded. It’s also common with page builders, heavy themes, and long plugin lists.

If you’re hitting the limits of shared hosting, moving WordPress to a VPS gives you consistent CPU/RAM. It also lets you set PHP limits without fighting the platform.

For hands-on control, start with a HostMyCode VPS. If you’d rather not manage updates, security patches, and service restarts yourself, managed VPS hosting is a better fit for business-critical sites.

If updates keep timing out—or you’re tired of fixing the same outage at 2 a.m.—run WordPress on hosting with consistent resources and sensible defaults. HostMyCode offers HostMyCode WordPress hosting for straightforward sites and a HostMyCode VPS for stores and multi-site setups that need more headroom.

FAQ

Is it always safe to delete the .maintenance file?

Yes. Deleting (or renaming) .maintenance only removes the maintenance lock. If an update is half-applied, you may still need to fix plugins/themes afterward.

Why does WordPress create .maintenance but not remove it?

WordPress removes it at the end of a successful update. It stays behind if PHP hits a timeout, runs out of memory, can’t write files, or the process is interrupted.

What if I can’t find .maintenance in my site root?

Either the message is coming from a plugin “maintenance mode” feature, a host-level maintenance page, or you’re checking the wrong directory. Confirm the folder with wp-config.php.

Will disabling plugins by renaming the folder delete settings?

No. Renaming wp-content/plugins only deactivates plugins. Most settings remain in the database and come back when you restore the folder.

How do I prevent update outages on a busy WooCommerce store?

Use a staging workflow, run updates in a maintenance window, ensure PHP has enough memory/time, and keep tested backups. If you’re migrating to a VPS, HostMyCode can help via HostMyCode migrations so you can fix the underlying resource constraints without a messy cutover.

Summary: the 10-minute recovery playbook

  1. Back up files + database.
  2. Find the real WordPress root (has wp-config.php).
  3. Rename .maintenance and refresh.
  4. If it still fails, read server logs or wp-content/debug.log.
  5. Disable plugins by renaming the plugins folder, then re-enable one at a time.
  6. Fix PHP limits, permissions, and update workflow to stop repeat outages.

If you’re running this playbook more than once a quarter, it’s usually a hosting fit issue, not a mysterious WordPress quirk. A properly sized managed VPS hosting plan gives you room to update safely, plus operational help when something still goes sideways.