
Your WordPress site can get stuck on “Briefly unavailable for scheduled maintenance” after an update that times out, runs out of disk space, or hits a permissions problem. The fix is usually quick. You can fix WordPress maintenance mode in a few minutes—without rolling back the site—by removing the lock file and confirming the update finished cleanly.
This walkthrough assumes a real server (VPS, or shared hosting with SSH). You’ll confirm the correct WordPress root, remove the lock safely, verify core/plugins/themes aren’t half-updated, and fix the settings that usually cause repeat lockouts.
What “maintenance mode” really means (and why it gets stuck)
During updates, WordPress drops a small lock file named .maintenance into the WordPress root. This is the same directory as wp-config.php. While that file exists, WordPress shows the maintenance message to visitors.
On a normal update, WordPress deletes .maintenance at the end.
If PHP crashes, the server runs out of space, ownership/permissions block writes, or an update hangs, the cleanup never runs.
The update may even finish, but the leftover lock still keeps the site “down.”
Before you change anything: confirm the WordPress root
First, make sure you’re deleting the correct .maintenance file. VPS setups often host several sites under /var/www. Shared hosts usually place WordPress under public_html.
- Common Nginx roots:
/var/www/example.com/public,/var/www/html,/usr/share/nginx/html - Common Apache roots:
/var/www/example.com/public_html,/var/www/html - cPanel:
/home/USERNAME/public_html(or an add-on domain subfolder)
Find it quickly with SSH:
cd /var/www
sudo find . -maxdepth 4 -name wp-config.php 2>/dev/null
Choose the directory that matches your domain. The WordPress root is the folder that contains wp-config.php.
If you’re on a HostMyCode VPS, SSH access lets you fix this cleanly. You avoid guessing in a file manager.
See HostMyCode VPS for an isolated environment where your updates aren’t competing with other tenants.
Step 1 — Check whether the .maintenance lock exists
Move into your WordPress root (replace the path with your own):
cd /var/www/example.com/public_html
Check for the lock file:
ls -la .maintenance
If it exists, you’ll get a file listing.
If you see No such file or directory, the lock file isn’t the immediate cause. Skip ahead to the troubleshooting sections below.
Optional but helpful: inspect the file contents. WordPress often writes a timestamp.
cat .maintenance
Step 2 — Remove the maintenance lock safely
Deleting .maintenance is safe. You are not deleting WordPress. You are removing the “block visitors” flag.
rm -f .maintenance
Verify it’s gone:
test ! -f .maintenance && echo "Lock removed"
Verify in your browser: load the homepage and /wp-admin/. If both load normally, the incident is resolved.
Next, confirm the update didn’t stop halfway.
Step 3 — Confirm the update didn’t half-apply
A leftover lock often means the update process was interrupted. Take a minute to confirm WordPress core, plugins, and themes are consistent.
You want to catch partially extracted files now, not later.
Option A (recommended): use WP-CLI
On a VPS, WP-CLI is the fastest way to check status and finish whatever WordPress didn’t complete.
On Ubuntu/Debian:
sudo apt-get update
sudo apt-get install -y curl php-cli php-mbstring
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
php wp-cli.phar --info
chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp
From your WordPress root:
wp core version
wp plugin status --skip-plugins --skip-themes
wp theme status --skip-plugins --skip-themes
Finish any pending updates:
wp core update
wp plugin update --all
wp theme update --all
Verify:
wp core verify-checksums
If checksums pass, WordPress core files match the official release for that version.
Option B: no WP-CLI (shared hosting or limited access)
Log in to /wp-admin/ and review these areas:
- Dashboard → Updates (run updates again even if it “looks done”)
- Plugins → Installed Plugins (watch for “update failed” notices)
- Appearance → Themes (re-run theme updates)
If you can’t access wp-admin due to errors, jump to the “If the site loads but wp-admin is broken after the fix” section.
Step 4 — Fix the common root causes so it doesn’t happen again
Removing .maintenance makes the site visible again. Preventing the next lockout usually comes down to four issues: disk pressure, permissions, PHP limits, and update timing.
4.1 Check disk space (the silent update killer)
Low disk space causes partial downloads and failed extraction. It’s one of the most common reasons updates get stuck.
df -h
sudo du -xh /var/www --max-depth=2 | sort -h | tail -n 20
What you want: a few GB free on the partition that stores your site.
If / is above ~90% used, treat updates as high-risk until you reclaim space.
Quick wins:
- Clear old logs in
/var/log(carefully) or tune logrotate - Remove unused Docker images if you run containers on the same VPS:
docker system prune - Clean old backups from the same disk (backups belong offsite)
4.2 Fix WordPress file ownership and permissions
Ownership problems are common after migrations, manual uploads, or running WordPress commands as root.
The symptom is consistent: PHP can’t write into wp-content. Updates fail, and the lock never clears.
Find your web server user:
- Ubuntu/Debian Apache: typically
www-data - Ubuntu/Debian Nginx + PHP-FPM: often
www-data, but can be per-site user - AlmaLinux/Rocky/CentOS Stream Apache: typically
apache
Check ownership on the usual write targets:
ls -ld . wp-content wp-content/uploads
Typical safe baseline on a single-site VPS (adjust user/group):
# Ubuntu/Debian example
sudo chown -R www-data:www-data /var/www/example.com/public_html
sudo find /var/www/example.com/public_html -type d -exec chmod 755 {} \;
sudo find /var/www/example.com/public_html -type f -exec chmod 644 {} \;
If you run WordPress under a separate deploy user (a good pattern), keep most files owned by that user.
Then grant the PHP-FPM pool write access only where needed (typically wp-content/uploads).
For a deeper, WordPress-specific permissions walk-through, use this WordPress file permissions fix on a VPS guide and match it to your stack (Nginx/Apache, PHP-FPM, and your user model).
4.3 Increase PHP limits that commonly break updates
Plugin and theme updates can hit timeouts or memory ceilings. This is more likely on smaller VPS plans or sites running heavy page builders.
Find your active PHP-FPM pool config:
- Ubuntu/Debian:
/etc/php/8.3/fpm/pool.d/www.conf(or a per-site pool) - AlmaLinux/Rocky with Remi PHP:
/etc/opt/remi/php83/php-fpm.d/www.conf
Find the active php.ini for FPM:
php --ini
That output is for CLI, not FPM. For FPM, check:
sudo php-fpm8.3 -i 2>/dev/null | grep -E "Loaded Configuration File|memory_limit|max_execution_time"
If your binary name differs, list FPM services:
systemctl list-units --type=service | grep -i fpm
Practical update-friendly values (not extreme):
memory_limit = 256M(or 512M for heavy builders)max_execution_time = 180max_input_time = 180post_max_size = 64Mupload_max_filesize = 64M
Edit the appropriate file, then reload services. Examples:
# Nginx + PHP-FPM
sudo systemctl reload php8.3-fpm
sudo systemctl reload nginx
# Apache + PHP-FPM
sudo systemctl reload php8.3-fpm
sudo systemctl reload apache2
Verify from WordPress: Tools → Site Health → Info → Server, and confirm the new limits show up.
4.4 Stop WordPress from trying to update during traffic spikes
On a small VPS, updates during peak traffic can starve PHP workers and stall the updater.
If the request times out at the wrong moment, the lock file can stick.
Two habits prevent most of this:
- Run updates during low-traffic windows.
- Use a staging copy for major plugin/theme changes, then deploy.
If you don’t want to manage staging and server tuning yourself, managed VPS hosting can be a better fit for production WordPress where uptime matters more than server maintenance.
If it keeps coming back: identify what’s recreating .maintenance
If .maintenance reappears right after you delete it, something is still attempting updates in a loop.
The usual causes are broken auto-updates, a stuck cron queue, or a plugin update that fails and immediately retries.
Check WordPress cron (a frequent culprit)
A backed-up cron queue can retrigger background updates. If cron is unhealthy, fix that first.
Use this guide and apply it to your VPS stack: fix WordPress cron not running on a VPS.
Quick test with WP-CLI:
wp cron event list --fields=hook,next_run,action --skip-themes --skip-plugins | head
If you see a flood of update-related hooks, that’s your loop.
Disable auto-updates temporarily to stabilize
While you debug, stop repeat attempts by adding this to wp-config.php (above “That’s all, stop editing!”):
define('WP_AUTO_UPDATE_CORE', false);
define('AUTOMATIC_UPDATER_DISABLED', true);
Once the underlying problem is fixed, remove those lines so you don’t miss security updates.
If the site loads but wp-admin is broken after the fix
Maintenance mode sometimes hides the real issue.
Common causes include a plugin update that triggered a fatal error, or a theme update that doesn’t match your PHP version or server limits.
1) Check web server error logs
Nginx:
sudo tail -n 100 /var/log/nginx/error.log
Apache (Ubuntu/Debian):
sudo tail -n 100 /var/log/apache2/error.log
PHP-FPM: common paths include:
/var/log/php8.3-fpm.log/var/log/php8.3-fpm/www-error.log
sudo tail -n 120 /var/log/php8.3-fpm.log 2>/dev/null || true
sudo journalctl -u php8.3-fpm --since "30 min ago" --no-pager | tail -n 120
Scan for errors like “Allowed memory size exhausted”, “PHP Fatal error”, “Permission denied”, or “No space left on device”.
Fix what the log points to. Then re-run the update.
2) Disable the last-updated plugin quickly (no dashboard needed)
If the logs point to a plugin, disable it by renaming its folder:
cd /var/www/example.com/public_html/wp-content/plugins
ls -lt | head
Rename the suspected plugin directory:
mv plugin-name plugin-name.disabled
Reload the site. If it stabilizes, reinstall or update that plugin cleanly later.
3) Check for a partially extracted plugin/theme
A failed unzip can leave a directory missing key files. Look for unusually empty folders or incomplete plugin directories:
find wp-content/plugins -maxdepth 2 -type d -name "*" -exec sh -c 'echo "---"; echo "$1"; ls -1 "$1" | head' sh {} \; | head -n 80
If you find a broken plugin folder, delete it and reinstall from a known-good source (WordPress repo or the vendor download).
Hardening step: add a real backup + restore test before updates
Getting stuck in maintenance mode is irritating. Discovering your backups don’t restore is worse.
On a VPS, treat backups as normal operations, not an optional add-on.
- Back up files (WordPress directory).
- Back up the database (MySQL/MariaDB).
- Do a restore test to a temporary directory or staging site.
If your WordPress uses PostgreSQL (less common, but it happens), follow this pg_dump backup and restore test tutorial and adapt it to your schedule and retention.
For most WordPress installs on MySQL/MariaDB, a practical baseline looks like this (run from a secure backup directory):
# database dump (replace DB name/user)
mysqldump --single-transaction --quick --routines --triggers \
-u wpuser -p wpdatabase | gzip > wpdatabase-$(date +%F).sql.gz
# files backup
tar -czf wpfiles-$(date +%F).tar.gz /var/www/example.com/public_html
Store those backups off the server.
If they sit on the same disk that fills up, they won’t help when you need them.
Quick verification checklist (use this every time)
- Homepage loads and doesn’t show the maintenance message.
- /wp-admin/ loads and you can log in.
- Disk space:
df -hshows safe headroom. - Permissions: web server user can write to
wp-content/uploads. - Logs are clean: no repeating fatal errors in Nginx/Apache/PHP-FPM logs.
- Updates complete: WordPress shows no pending core/plugin/theme updates.
Common mistakes that keep sites stuck
- Deleting the wrong .maintenance (not the WordPress root). Always locate
wp-config.phpfirst. - Clearing the lock but ignoring disk usage. If you’re at 95% full, expect a repeat.
- Running updates as root. That often changes ownership and breaks the next update.
- Blaming WordPress alone. Web server and PHP logs usually tell you exactly what failed.
Summary: fix WordPress maintenance mode, then make updates boring
To restore the site, delete the .maintenance file from the WordPress root. Then confirm the homepage and /wp-admin/ load.
After that, check the three items that prevent most repeats: disk headroom, correct ownership/permissions, and PHP limits that can handle real-world updates.
If you run production WordPress on your own infrastructure, a VPS gives you predictable resources and direct access to logs.
For hands-on site owners, HostMyCode VPS is a solid fit. If you’d rather not maintain the server layer, managed VPS hosting keeps updates and stability from turning into a weekend job.
If your WordPress site is business-critical, run it on a VPS where you control PHP limits, disk headroom, and server logs. Start with a HostMyCode VPS, or choose managed VPS hosting if you want the server maintained for you while you focus on the site.
FAQ: fixing WordPress maintenance mode
Will deleting .maintenance break my WordPress site?
No. Deleting it removes the maintenance lock so WordPress stops showing the message. If an update failed mid-way, you may still need to rerun the update.
What if .maintenance is not there but I still see the message?
Clear every caching layer involved (plugin cache, Nginx cache, CDN). Then confirm you’re working in the correct document root—multiple WordPress copies are common on VPS hosts.
Also check whether your CDN is serving a cached maintenance page.
Why does my site get stuck after plugin updates specifically?
Plugin updates fail most often because WordPress can’t write to wp-content/plugins, the disk is too full to extract the update, or PHP hits memory/time limits.
Check server/PHP logs and fix the constraint they point to.
Can I prevent this without disabling auto-updates?
Yes. Keep disk space available, set correct ownership so PHP can write to wp-content, and use reasonable PHP limits.
Also run backups with a restore test so you can recover quickly if an update goes sideways.
Do I need SSH access to fix this?
SSH is the quickest option, but you can delete .maintenance from a hosting file manager as well.
On shared hosting, it’s usually under public_html. On a VPS, locate wp-config.php first so you’re working in the correct WordPress root.