You click Add Media, choose the photo, and WordPress hands you a red banner instead of an image: unable to create directory wp-content/uploads/2026/07. Is its parent directory writable by the server?
Nothing uploads. The post is half-finished. The client is refreshing the page.
Take the pressure off first: your site isn't broken. This is a filesystem permissions problem, and it's one of the tidiest fixes in WordPress — usually about five minutes, no plugins, no reinstall.
Quick Answer (as of July 2026): The "unable to create directory wp-content/uploads" error means PHP lacks write access to the uploads folder or its parent. Fix it by setting the folder's ownership to the user PHP runs as, then setting directories to 755 and files to 644. If the folder is missing, recreate it. A full disk quota and a stale upload path are the two causes nobody warns you about.
Between shared hosting, VPS boxes and WordPress installs, the Hostaccent team clears 20-30 client issues a day, and this error walks through the queue most weeks. Everything below is the same sequence our engineers run — written so you can do it yourself, right now, without opening a ticket.
What "Unable to Create Directory wp-content/uploads" Actually Means
WordPress doesn't dump your images into one flat folder. It creates a year and month subfolder — wp-content/uploads/2026/07 — the first time you upload in that month. That creation step is a PHP mkdir() call, and mkdir() runs as whatever system user your web server uses.
So the question in the error message is literal. Is its parent directory writable by the server? WordPress is telling you that the PHP process tried to create a folder and the operating system said no.
Two things decide that answer:
- Ownership — who the folder belongs to (
www-data,apache,nginx, or your cPanel username). - Permission bits — what that owner is allowed to do (the 755/644 numbers).
Here's the part almost every guide gets wrong: the failure is far more often ownership than permission bits. Chmod alone patches the symptom, works for a day, then breaks again. Fix the owner and the problem stays fixed.
Pro Tip: The date in the path (
/2026/07) fools people into thinking the year folder is the bug. It isn't. The month folder simply happens to be the first thing WordPress tries to create, so it's where the permission wall shows up first. Deleting or renaming it changes nothing.
The Causes, Ranked by How Often We See Them
Work down this list in order. The top two account for the overwhelming majority of cases.
1. Wrong ownership after a migration, restore or manual file copy. Someone unzipped a backup over SFTP as root or as a different account. The files now belong to that user, and PHP — running as someone else — can't write into them. In the migration tickets we handle, this is the single most common trigger.
2. Permissions tightened too far. A hardening plugin or a well-meant "security fix" set wp-content to 555 or 700. Uploads die instantly.
3. The uploads folder is gone entirely. Deleted during a cleanup, skipped by a partial restore, or never created by a manual install.
4. Disk quota or inode limit reached. The folder is perfectly writable — there's just no room. The error message doesn't say so, which is why this one burns hours.
5. A stale upload_path in the database. After a migration, the old absolute server path is still sitting in wp_options, pointing WordPress at a directory that doesn't exist on the new server.
6. SELinux, open_basedir or an immutable flag. Rare on managed hosting, common on self-managed VPS boxes. PHP's own file upload handling is fine — the kernel or the PHP config is refusing the write.
From the Ticket Queue: WordPress issues make up 30% of Hostaccent's monthly support tickets, ahead of brute-force and malware at 25%, Linux server issues at 25%, and SSL problems at 20%. Within that WordPress slice, permission and ownership faults are the most repeated single theme — first-party numbers from our own support desk.
The Step-by-Step Fix: Ownership, Permissions, and Path
Answer first: set the correct owner, then 755 on directories and 644 on files, then clear the upload path. That's the whole fix. Here it is properly.
Step 1 — Find the user PHP actually runs as
Don't guess. Create a file called whoami.php in your site root:
php<?php echo exec('whoami'); ?>
Load yoursite.com/whoami.php, note the output, then delete the file immediately — leaving it up is a small but real information leak.
You'll see something like www-data (Debian/Ubuntu), apache (CentOS/RHEL), nginx, or your account name on cPanel-style hosting. On SSH you can shortcut it:
bashps aux | grep -E 'php-fpm|apache2|httpd' | head -5 ## column 1 is the user
Step 2 — Fix ownership (the step that makes it stick)
Replace www-data with your real user and the path with your real document root:
bashsudo chown -R www-data:www-data /var/www/yoursite.com/wp-content/uploads
If the whole install came over in a migration, do the lot:
bashsudo chown -R www-data:www-data /var/www/yoursite.com
No SSH? cPanel and Plesk File Manager can't change ownership — that's a genuine limitation, not you missing a button. On that setup, skip to Step 3, and if permissions alone don't fix it, ownership is the culprit and it needs a host-side hand.
Step 3 — Set uploads folder permissions correctly
Directories get 755. Files get 644. Never the same number for both:
bashcd /var/www/yoursite.com sudo find . -type d -exec chmod 755 {} \; ## directories sudo find . -type f -exec chmod 644 {} \; ## files
Now, the warning that matters: do not chmod 777. It's the most-repeated bad advice on this error. 777 lets any process on the server write executable files into your uploads folder — and when a hacked site lands in our queue, wp-content/uploads is one of the first places our team traces backdoor shells to. It "fixes" uploads for a week and buys you a malware cleanup. The changing file permissions documentation on wordpress.org says the same thing in gentler language.
Live site and no time to experiment? Our engineers fix this exact error for a small one-time fee, and you'll see the exact quote before anyone touches a file. Hosted with Hostaccent? Then an upload permission fault is simply covered by support — no fee, no ticket-tennis. Have an engineer fix it
Step 4 — Recreate the folder if it's missing
bashmkdir -p /var/www/yoursite.com/wp-content/uploads sudo chown -R www-data:www-data /var/www/yoursite.com/wp-content/uploads sudo chmod 755 /var/www/yoursite.com/wp-content/uploads
Create it, then own it, then chmod it. In that order — a folder created by root and left that way puts you straight back where you started.
Step 5 — Clear the stale upload path
Go to Settings → Media in wp-admin. If "Store uploads in this folder" contains anything — especially an old absolute path like /home/olduser/public_html/wp-content/uploads — empty the field and save. WordPress defaults to the correct relative path when it's blank.
The field is hidden on most modern installs. Reach it directly at yoursite.com/wp-admin/options.php and look for upload_path, or clear it with WP-CLI:
bashwp option update upload_path '' wp option update upload_url_path ''
Using WP-CLI, we run mass operations across client sites, and this pair of commands is on the standard post-migration checklist for exactly one reason: we found that a leftover upload_path row silently survives nearly every manual database export.
When It Isn't Permissions: Disk Space, SELinux, and Multisite
Ran every step and still stuck? Then it's one of the quiet three.
Disk or inode quota. Check it:
bashdf -h ## disk space df -i ## inodes — a small site with huge cache dirs can exhaust these first
On cPanel, the control panel's disk usage meter tells you the same thing in two clicks. A full quota produces this identical error, and there is no clue in the message. Clear old backups and cache files, or move up a plan.
SELinux (CentOS, Rocky, AlmaLinux):
bashls -Z /var/www/yoursite.com/wp-content/uploads sudo chcon -R -t httpd_sys_rw_content_t /var/www/yoursite.com/wp-content/uploads
open_basedir. If your PHP-FPM pool restricts paths, the uploads directory must sit inside them. Check with a phpinfo() page, and consult Apache's own documentation if a vhost-level rule is fighting you.
Multisite. Subsites write to wp-content/uploads/sites/{ID}/. That sites folder needs the same owner and 755 — fixing only the parent leaves every subsite broken.
Insider Insight: Turn the guessing off. Add
define('WP_DEBUG', true);anddefine('WP_DEBUG_LOG', true);towp-config.php, retry the upload, then readwp-content/debug.log. A quota problem and an ownership problem produce the same banner in wp-admin but completely different log lines. The debugging in WordPress guide covers the flags. SetWP_DEBUGback tofalsewhen you're done.
Confirm the Fix and Stop It Coming Back
Upload a small JPEG. If it lands, you're done — but spend 60 seconds confirming it properly, because a fix that works once and fails next month isn't a fix.
Call it the 60-second uploads triage, and run it in this order every time:
- Upload an image. Success on the first try means ownership is right.
- Check the folder was born correctly:
ls -la wp-content/uploads/2026/— the new month folder should show your PHP user as owner, not root. - Check headroom:
df -handdf -i. Under 90% on both. - Check the media library renders. A file that uploads but shows a broken thumbnail is a URL problem, not a permissions one.
To keep it fixed: stop unzipping backups as root (sudo -u www-data unzip site.zip), don't let a security plugin manage permissions automatically, and check quota before it bites. If uploads worked, then broke after "nothing changed", something changed — a restore, a plugin, or a full disk. Those three cover nearly all repeats.
While you're in there, it's worth knowing that upload failures and slow pages usually share a root cause. Our WordPress Site Slow: Complete Diagnosis and Fix Guide (2026) walks the same filesystem angle, and if the site got sluggish around the same time, How to Fix High TTFB in WordPress (2026 Guide) is the next stop. A 500 error appearing alongside upload failures usually points at the same botched restore — 500 Internal Server Error WordPress: Fix It Fast (2026) covers that pairing.
Your Next Step: Uploads That Aren't Your Problem
Path A — you fixed it. Good. Keep one takeaway: ownership, not chmod. If you remember chown before chmod for the rest of your WordPress life, "unable to create directory wp-content/uploads" never comes back.
And here's the honest observation. You just spent your afternoon on a filesystem permission bit. On a properly managed host, this class of problem is support's job — you send one message and go back to work. That's the whole point of Hostaccent: a UK-registered company (Companies House 11431799, incorporated 2018), trading since 2012, 10,000+ sites launched and 4,000+ migrations behind us, with a 99.9% uptime guarantee and 30 days to change your mind. Managed WordPress Hosting starts on the Basic plan — $22.99/yr, renewing at $22.99/yr — on NVMe SSD storage with free SSL and daily backups. Running something simpler than WordPress? Start on the Economy shared hosting plan — $1.99/mo — instead. And if the name is still on someone else's registrar, move your .com over at $13.99/yr, flat at renewal and run domain, hosting and support from one dashboard with one renewal date. One honest caveat: Basic is sized for a single WordPress site — juggling several client projects, take Medium at $8.99/mo.
Path B — still stuck. Send it to us. Our engineers fix this exact error for a small one-time fee, and you'll have the quote in front of you before any work begins. Open a ticket with an engineer and tell us what you've already tried — it saves us both a round trip.
Frequently Asked Questions
Why does WordPress say unable to create directory wp-content/uploads?
Because PHP tried to create the month subfolder and the operating system refused. Nine times out of ten, the uploads folder belongs to a different system user than the one PHP runs as — usually after a migration or a backup unzipped as root. Fix the ownership with chown, then set 755 on directories.
What does "is its parent directory writable by the server" mean?
It's WordPress telling you the web server process lacks write permission on the folder above the one it's trying to create. "The server" means the PHP user — www-data, apache, nginx, or your hosting account name. It's a literal question about filesystem access, not a hint about your hosting plan.
Is 777 safe for wp-content/uploads?
No. 777 lets every process on the server write into your uploads folder, and that folder is a favourite hiding spot for backdoor shells. It looks like a fix because it works instantly. Use 755 on directories and 644 on files, and correct the ownership instead — that's the real solution.
What do I do when WordPress cannot upload images at all?
Work the list in order: check the PHP user, fix ownership, set 755/644, clear the upload path in Settings → Media, then check disk and inode quota with df -h and df -i. Enable WP_DEBUG_LOG and read debug.log — it names the actual failure instead of guessing.
Can I fix uploads folder permissions without SSH access?
Partly. cPanel or Plesk File Manager can change permission bits to 755, which resolves the tightened-permissions cause. Ownership can't be changed from File Manager — that needs shell or your host. The engineers on the Hostaccent support desk handle ownership resets for clients as a standard request, no fee.
Why did uploads break when I changed nothing?
Something changed, just not by you. The usual three: a plugin auto-update that re-hardened permissions, a backup or staging push that rewrote file ownership, or a disk quota that quietly filled with cache and old backups. Check df -h first — it takes two seconds and rules out the sneakiest cause.











Discussion
Have a question or tip about this topic? Share it below — your comment will appear after review.