Backups Fail Silently on CloudPanel / nginx / OpenLiteSpeedPRO
If SiteVault Pro backups fail without an actionable error on a managed-host stack — usually with a “cannot create backup directory” message on 1.7.31+ — the cause is almost always filesystem permissions on the wp-content/uploads/ tree. Two layers to address: fix the permissions so PHP can create the directory, then add the web-server rule that keeps the backups themselves unreachable. Here’s both, per server.
Symptoms
You probably have this issue if one or more of the following are true:
On SiteVault Pro 1.7.31 and later
- Backup row shows status Failed with an error message like: “Backup cannot start: cannot create backup directory at /wp-content/uploads/sitevault/backups. Check filesystem permissions on the parent directory and any server-level rules.”
- The error names the exact directory that can’t be created
- SSH access shows
wp-content/uploads/sitevault/either doesn’t exist OR exists but the PHP user can’t write to it
SiteVault 1.7.31 added a pre-flight check that surfaces the exact directory that can’t be created. Pre-1.7.31 the failure was silent and the row just said “Backup in progress or failed” with no detail — if you’re on an older version, update to 1.7.31+ first to get the proper error message before debugging.
On SiteVault Pro pre-1.7.31
- Backups row in the dashboard shows status Failed with the generic “Backup in progress or failed” message and no detail
- No
.zipever appears in the backups directory (because the directory itself was never created) - Database-only backups do complete when written to a different directory, but full backups don’t
- The
wp-content/uploads/sitevault/directory is missing entirely or empty
How to Verify It’s This Specific Issue
Two quick checks confirm the diagnosis before you change any server config.
Check the parent directory’s writability as the PHP user
From an SSH terminal in your WordPress root. The check tests whether the PHP user can write to wp-content/uploads/ — that’s the parent SiteVault needs to create sitevault/ inside. Checking the missing sitevault/ directory directly would always fail (it’s missing — that’s the symptom we’re diagnosing).
ls -la wp-content/uploads/sitevault/ 2>/dev/null || echo "SITEVAULT DIRECTORY MISSING"
PHP_USER=$(stat -c '%U' wp-config.php)
sudo -u "$PHP_USER" touch wp-content/uploads/.write-test \
&& rm wp-content/uploads/.write-test \
&& echo "UPLOADS WRITABLE BY $PHP_USER" \
|| echo "UPLOADS NOT WRITABLE BY $PHP_USER"If you see UPLOADS NOT WRITABLE BY ..., you’ve confirmed the cause — the PHP user can’t create subdirectories under uploads/. Go to Layer 1 below to fix ownership.
(Optional) Check the web-access protection state
From your local machine, curl the directory URL:
curl -I https://yoursite.com/wp-content/uploads/sitevault/
A 403 Forbidden means the web-access protection (Layer 2 below) is already in place — good. A 200 OK or 404 with a directory listing means you’ll need the server-block rule from Layer 2 once you have a working backup directory. This check is informational; it doesn’t tell you anything about why wp_mkdir_p failed (that’s the filesystem layer, separate from the HTTP layer).
(Optional) Check Tools → Site Health
In wp-admin go to Tools → Site Health → Info → Filesystem Permissions. The The uploads directory row should say Writable. If it says Not writable, your uploads directory itself is locked — fix that first, then re-test SiteVault.
The Fix — Two Layers
There are two separate problems to solve, and it’s easy to conflate them. Do them in this order:
- Fix the directory-creation failure — this is a filesystem-layer issue (Linux file permissions, PHP’s
open_basedir, or in rare cases SELinux/AppArmor). The web server’s config doesn’t directly control whether PHP’smkdir()syscall succeeds. - Protect backups from being downloaded by URL guessing — this is a web-server-layer issue. SiteVault auto-writes
.htaccess+web.config+ a stubindex.phpinto the backup directory, which Apache and IIS honor. nginx and OpenLiteSpeed don’t read.htaccess, so on those servers you need an explicit vhost rule.
The 1.7.31 error message reads “Check filesystem permissions on the parent directory and any server-level rules (e.g. nginx `deny all` on /wp-content/uploads/sitevault/)”. The nginx hint is included because some managed-host stacks mirror their nginx deny rules at the filesystem layer via custom security wrappers — in those edge cases, relaxing the nginx rule does fix the creation. But the most common cause by far is straightforward filesystem permissions, which the Layer 1 steps below address.
Layer 1: Fix Directory Creation (the actual cause)
SSH in and identify the PHP user
The PHP user is whoever owns wp-config.php:
cd /path/to/your/wordpress stat -c '%U:%G' wp-config.php
Typical values: www-data:www-data (vanilla nginx/Apache), cloudpanel:cloudpanel (CloudPanel), a per-site user like site-myname:site-myname (managed hosts).
Confirm the parent directory is owned by that user and is writable
ls -la wp-content/uploads/
The uploads entry should show the same owner you got in the previous step, with mode 755 or 775. If the owner is different (e.g. root or some deploy user), that’s your cause — PHP can’t create subdirectories under a directory it doesn’t own.
Fix ownership if needed
From SSH. Uses %U:%G to pull both the user AND the primary group from wp-config.php — safer than assuming the group has the same name as the user (which is the default on most distros but not universal).
sudo chown -R $(stat -c '%U:%G' wp-config.php) wp-content/uploads/ sudo chmod 755 wp-content/uploads/
Manually create the SiteVault directory tree (skips the WP layer)
If WordPress is still struggling, just create the directories yourself with the right ownership — SiteVault will use them on the next backup:
PHP_USER=$(stat -c '%U' wp-config.php)
sudo -u "$PHP_USER" mkdir -p \
wp-content/uploads/sitevault/backups \
wp-content/uploads/sitevault/temp \
wp-content/uploads/sitevault/logsTrigger a fresh backup from SiteVault Pro → Backups → Backup Now. The 1.7.31 pre-flight check should now pass.
If still failing — check open_basedir and disk space
Two remaining filesystem-layer culprits:
- open_basedir restriction: some hosts limit PHP to a whitelist of paths. From the WP admin Tools → Site Health → Info → Server tab, find “PHP open basedir”. If it’s set, the WordPress installation path must be inside the listed paths. Contact your host if it isn’t.
- Disk space / quota:
df -hand (on hosts with per-user quotas)quota -s. Out-of-disk produces the same “cannot create” symptom.
Layer 2: Protect Backups from Web Access (security)
After Layer 1 makes backups work, the backup files themselves need to be unreachable by URL guessing — they contain your full database dump and wp-config.php. On Apache and IIS the protection is automatic (SiteVault writes .htaccess and web.config). On nginx and OpenLiteSpeed you have to add a vhost rule because those servers don’t read .htaccess.
If the backup directory ends up web-accessible, SiteVault Pro 1.7.26+ probes it via a short-lived canary file and shows a red admin notice on every page load until you fix it. So you’ll know to come back here even if you skip this layer initially.
CloudPanel + plain nginx
Open your site’s vhost config (CloudPanel: /etc/nginx/sites-enabled/<site>.conf; Debian/Ubuntu: /etc/nginx/sites-available/yourdomain.conf; CentOS/RHEL: /etc/nginx/conf.d/yourdomain.conf). Inside the server { ... } block, add:
location ~* /wp-content/uploads/sitevault/ {
deny all;
return 403;
}Then reload nginx:
sudo nginx -t && sudo systemctl reload nginx
OpenLiteSpeed
Open the OLS admin panel
Navigate to Virtual Hosts → (your site) → Context (usually at port 7080).
Add a new Static Context
Click Add → Static. Set URI: /wp-content/uploads/sitevault/, Access Allowed: No. Save.
Graceful restart OLS
Actions → Graceful Restart in the admin panel.
LiteSpeed Web Server (Enterprise) + Apache
Both honor the .htaccess SiteVault writes into the backup directory automatically — no extra config needed.
Why Does This Happen?
Two separate things are going on, and the failure conflates them in a way that’s easy to mis-diagnose.
The creation failure (Layer 1)
SiteVault Pro stores backups under wp-content/uploads/sitevault/. The first time it runs a backup, it needs to create that directory tree. wp_mkdir_p() — the WordPress wrapper around PHP’s mkdir() syscall — can fail silently for a handful of filesystem-layer reasons:
- The PHP user doesn’t own
wp-content/uploads/— common on managed hosts where a deploy script created the WordPress install as one user, but PHP-FPM runs as a different user. PHP can read the directory but can’t create subdirectories under it. open_basedirrestriction — some hosts restrict PHP to a whitelist of paths viaphp.ini. If the install path isn’t in the whitelist, every filesystem call fails.- SELinux / AppArmor / custom security wrappers — rare but real on hardened stacks. Some managed-host setups mirror their nginx deny rules at the filesystem layer via these mechanisms, which is what the plugin error message is hinting at when it mentions “server-level rules”.
- Disk space / per-user quotas — produces the same “cannot create” symptom.
Before 1.7.31, wp_mkdir_p()’s return value was discarded by the plugin, so the failure was invisible and the backup just crashed mid-run with a generic error. 1.7.31 checks the return value and surfaces the exact path that failed, which is what lets you actually fix it.
The web-access protection (Layer 2)
The backups themselves contain your full database dump plus wp-config.php — anyone with a URL guess could download them. SiteVault writes a deny all rule into .htaccess AND web.config AND a stub index.php guard the moment the directory is created.
Apache honors .htaccess. IIS honors web.config. nginx ignores both, and so do OpenLiteSpeed and some LiteSpeed configurations — their web-server config has to be edited at the vhost level. That’s why the Layer 2 step is required on those servers but not on Apache.
SiteVault Pro 1.7.26+ self-validates the protection: it probes the backup directory with a short-lived canary file via loopback HTTP, and shows a red admin notice if the canary is fetchable. So you’ll know if Layer 2 needs work even if you initially skipped it.
SiteVault Pro 1.7.31 added an explicit pre-flight check that names the exact directory that can’t be created, so you can ask your host the right question instead of getting a generic “backup failed”. If you’re on an older version, upgrading to 1.7.31+ is the first move — the error message gets you to this fix doc much faster.
Still Failing After the Server Config Change? Email Priority Support
If you’ve added the location block, reloaded the web server, and SiteVault still fails to create the backup directory, email support@royalplugins.com with the diagnostic info below. Priority email support is included with your SiteVault Pro license — typical response time is within 24 hours.
Information We’ll Need
- SiteVault Pro version (Plugins → Installed Plugins)
- The exact error message shown on the failed backup row (1.7.31+ will name the directory)
- Hosting provider name + control panel (CloudPanel, RunCloud, GridPane, ServerPilot, custom, etc.)
- Web server: nginx, OpenLiteSpeed, LiteSpeed Enterprise, Apache
- SSH output of
ls -la wp-content/uploads/ANDls -la wp-content/uploads/sitevault/ 2>/dev/null || echo MISSING - Last 50 lines of
wp-content/uploads/sitevault/logs/sitevault-YYYY-MM-DD.logif the directory exists - The location block you added (or a confirmation of which fix you tried)