Fixing the Could Not Create Directory Error
WordPress tried to write a folder and the server said no. The message does not say which folder or why, and the three usual reasons — ownership, a full disk, a missing upgrade directory — each need a different fix.
The server refused to create a folder, and the message hides which folder. "Installation failed: Could not create directory." is what the upgrader prints when a mkdir fails during a plugin, theme or core install. The failing path is one of a small set, the cause is one of a smaller set, and guessing at chmod 777 is the one response that makes the next problem worse.
Find the directory first
The path is not in the debug log — the failed mkdir is silenced — but it is in the installer's own output. Install from the upload form on Plugins › Add New › Upload Plugin rather than from the modal in the plugin directory: the page-based installer prints the message with the full path after it, "Could not create directory. /var/www/site/wp-content/plugins/slug/", while the modal shows only the bare sentence. The candidates:
| Path | When it is created |
|---|---|
wp-content/upgrade/ |
Every install and update: the zip is unpacked here first |
wp-content/plugins/<slug>/ or wp-content/themes/<slug>/ |
The final move |
| A folder inside the unpacked zip | A zip whose entries the extractor cannot create under upgrade/ |
Two neighbouring failures print different messages and are not this one: the rollback backup folder has its own wording, "Could not create the upgrade-temp-backup directory", and a media upload that cannot create its month folder says "Unable to create directory … Is its parent directory writable". If you see those, the cause is still ownership or disk, but the folder is a different one. For anything the installer does not say, the three-constant debug mode setup catches PHP warnings from the same request.
Cause 1: ownership, not permissions
WordPress writes as the user PHP runs under — www-data, apache, nginx, or the account name on shared hosting. If wp-content is owned by a different user with 755, that user can write and PHP cannot. The common path to this state is a deploy, migration or manual upload done as root or as an SFTP user, leaving files the web server does not own.
ls -ld wp-content wp-content/plugins wp-content/upgrade
ps -o user,comm -C php-fpm,php-fpm8.3,apache2,httpd | sort -u
The first command shows the owner; the second lists the users PHP processes run as — the master process is root, the workers are the user that matters. When they differ, change the owner, not the mode:
chown -R www-data:www-data wp-content
find wp-content -type d -exec chmod 755 {} \;
find wp-content -type f -exec chmod 644 {} \;
chmod 777 makes the folder writable by every account on the server, which on shared hosting means every other customer. It does solve the error. It also creates the condition behind most hacked sites on that kind of host.
Cause 2: the FS_METHOD trap
When PHP cannot write, WordPress normally asks for FTP credentials rather than failing. A site that shows this error instead of the FTP prompt has usually been told define( 'FS_METHOD', 'direct' ) in wp-config.php — which suppresses the prompt and makes WordPress write as the PHP user, which then fails. The constant is a way to hide a prompt, not a way to grant access; the full reasoning is in FS_METHOD. Remove the constant and fix ownership, or keep it after ownership is fixed.
Cause 3: disk, quota or inodes
A mkdir also fails when there is no room. Hosting quotas count both bytes and file count:
df -h .
df -i .
A full disk is obvious; an inode limit is not — the disk shows free space and the file count is maxed, often by cache plugins or a log that grew for a year. Clear the cache directory and rotate logs, then retry. Shared hosting panels report the same numbers under disk usage.
Cause 4: a leftover folder
An install that failed halfway leaves a partial folder in wp-content/plugins/<slug> or in upgrade/. The next attempt may report this error if the leftover has the wrong owner, or the destination folder already exists if it merely exists. Delete the partial folder over SFTP or SSH and install again.
Cause 5: open_basedir and hosting restrictions
Some hosts restrict PHP to specific directories with open_basedir. If wp-content/upgrade resolves to a path outside the allowed list — a symlinked wp-content is the classic case — the write is refused even with correct ownership, and because the mkdir is silenced nothing is logged. A one-line test file calling mkdir() on the same path without suppression prints the restriction. The fix is in the PHP configuration or with the host, not in WordPress.
Verify
Retry the install from the upload form. If it succeeds, open the plugin folder and confirm its owner matches the PHP user, so the next update does not fail. If it fails again, the message now carries a path you have not checked — compare its owner and free space with the steps above. If the wording has changed to name upgrade-temp-backup or an uploads folder, you have moved on to a different folder with the same two causes.
Frequently asked
- Usually wp-content/upgrade, where the zip is unpacked, or wp-content/plugins/<slug> and wp-content/themes/<slug>, the final destination. The path is printed after the message when you install from the upload form rather than the plugin-directory modal; it is not written to the debug log, because the failed mkdir is silenced.
- Only if the prompt was for FTP credentials and the web server can actually write the folder. If the folder is owned by another user, direct makes WordPress attempt the write itself and fail with the same message. Fix ownership first.
- A leftover folder from a previous failed install can be owned by a different user, or a quota is exceeded just by that plugin's size. Check the destination folder's ownership and free space rather than the general permissions.