Skip to content

How to fix "Could not create directory" in WordPress

WordPress asked the server to make a folder during an install or an update, and the server refused. The path printed after the message names the folder. Correct who may write to it, or set aside a wp-content/upgrade folder WordPress cannot use. Setting folders to 777 is not the fix.

By
WP Ministry
Published
Tested on
WordPress 7.1.3, PHP 8.3.35

In short

  • The path after the message is the folder WordPress could not make. Read it before you change anything.
  • A path inside wp-content/upgrade means WordPress stopped while unpacking. What it was about to install or update has not been touched.
  • A path inside wp-content/plugins or wp-content/themes means the unpacked files could not be moved into place.
  • WordPress empties wp-content/upgrade before each unpack. A leftover there only blocks an install when WordPress cannot delete it.
  • Forcing FS_METHOD to direct does not let WordPress write. It replaces the form that asks for FTP details with this message.
  • Leave updates alone until an install works. With a plugins folder it cannot write to, an update can empty a plugin's folder.

"Could not create directory." means WordPress asked the server to make a folder and the server refused. It is one of the general messages of the code that installs and updates plugins, themes, translations and WordPress itself, so it reads the same whichever of them you were installing.

The useful part is what comes after it. In most places WordPress adds the path of the folder it could not make, and that path says which of two jobs it was doing and which folder to look at.

Where you see it:

  • On the Add Plugins screen, on the plugin's card: "Installation failed: Could not create directory."
  • After uploading a .zip file: "Could not create directory." and the path, on a line of their own.
  • On the Plugins screen, under the plugin you were updating: "Update failed: Could not create directory." and the path.
  • On the Updates screen: "An error occurred while updating", the plugin's name, then the message and the path.
  • In WP-CLI: "Warning: Could not create directory." with the path in quotes.

What the path tells you

WordPress installs in two moves. It unpacks the download into a working folder, wp-content/upgrade, and then moves the unpacked folder into wp-content/plugins or wp-content/themes.

The path after the messageWordPress wasLook at
Ends in wp-content/upgrade, or is inside itUnpacking the downloadThe working folder. Nothing has been changed yet: a plugin you were updating is still at its old version.
Is inside wp-content/plugins or wp-content/themesMoving the unpacked files into placeThe plugins or themes folder.
No path, on a plugin's card on the Add Plugins screenMoving the unpacked files into placeThe plugins folder. The card prints a path only when the unpacking fails.

"Could not copy file." is the same refusal one step later. The folder was there, and the file WordPress tried to write into it was refused. Everything on this page applies to it.

Where it goes wrong

A page request passes through each of these in turn. This one comes from the site's files.

  1. Browser
  2. DNS
  3. HTTPS
  4. CDN or firewall
  5. Web server
  6. PHP
  7. WordPress
  8. Database and files (this error comes from here)

What causes it

How to fix it

Find the folder that refuses, and why

  • Easy
  • No risk
  • About 10 minutes
  • Steps tested on WordPress 7.1.3
  1. Step 1: Read the path after the message

    It names the folder WordPress could not make. The folder to check is the one above it: for wp-content/plugins/example-plugin/, that is wp-content/plugins.

  2. Step 2: See what WordPress says it can write to

    Go to Tools, then Site Health, open the Info tab and then "Filesystem Permissions". It lists "The wp-content directory", "The plugins directory" and "The themes directory", each as "Writable" or "Not writable". It has no line for wp-content/upgrade, so a list of "Writable" does not clear the working folder.

  3. Step 3: List the folders with their owners

    Use your host's file manager or an SFTP program, which show each folder's permissions and owner. Over SSH, run this from the folder WordPress is installed in:

    bash
    ls -la wp-content
  4. Step 4: Read the listing

    The line for . is wp-content itself. Each line gives the mode, then the owner and the group. Two things stop WordPress making a folder inside another:

    • The owner is not the user PHP runs as. Here upgrade belongs to root. Go to the fix for the working folder, or to the fix for ownership.
    • The owner's part of the mode has no w. Here plugins is dr-xr-xr-x, which is 555. Go to the next fix.

    The user PHP runs as is the owner of files WordPress wrote itself, such as the newest upload under wp-content/uploads. WordPress file permissions explains how to read a mode and how the two kinds of hosting differ.

    text
    drwxr-xr-x 7 example example 4096 Oct 10 09:12 .
    dr-xr-xr-x 4 example example 4096 Oct 10 09:12 plugins
    drwxr-xr-x 5 example example 4096 Oct 10 09:12 themes
    drwxr-xr-x 2 root    root    4096 Oct 10 09:12 upgrade
  5. Step 5: See whether direct writing is forced

    If it prints nothing, the setting is not there. A line that sets it to direct matters when the files do not belong to the user PHP runs as: see the fix for ownership.

    bash
    grep -n "FS_METHOD" wp-config.php
  6. Step 6: If every folder is writable and correctly owned

    Then check for room, in the fix for a full disk.

To undo it: Nothing to undo. These steps only read.

Give the folder its write permission back

  • Easy
  • Low risk
  • About 5 minutes
  • Steps tested on WordPress 7.1.3

This is the fix when the folder belongs to the right user and its mode has no w for that user. WordPress's own guidance for a folder is 755.

  1. Step 1: Set the folder to 755

    In an SFTP program or your host's file manager, open the folder's permissions and enter 755. Over SSH, with the folder from the message in place of wp-content/plugins:

    Change that one folder. Do not apply it to everything inside.

    bash
    chmod 755 wp-content/plugins
  2. Step 2: Install again

    Install the plugin or theme the way you tried before. With WP-CLI, give the plugin's name as it appears in its WordPress.org address, or the path of a .zip file, in place of plugin-slug:

    bash
    wp plugin install plugin-slug
  3. Step 3: If chmod is refused

    "Operation not permitted" means the folder does not belong to the account you are signed in with. Only a file's owner or the server's administrator may change its mode. Go to the fix for ownership.

Do not go past 755 to make the message go away. Where PHP owns the folder, 755 is enough. Where it does not, 777 opens the folder to every account on the server, and the cure is ownership.

To undo it: Set the folder back to the mode the listing showed, for example chmod 555 wp-content/plugins.

Set the working folder aside and let WordPress make a new one

  • Takes care
  • Low risk
  • About 10 minutes
  • Steps tested on WordPress 7.1.3

Use this when the path in the message ends in wp-content/upgrade or is inside it.

wp-content/upgrade holds nothing WordPress needs to keep. Before each unpack it deletes whatever is in the folder, and it makes the folder again when it is missing. So an ordinary leftover from an install that stopped is cleared without your help. The folder is the cause only when WordPress may not write to it, or when something inside it cannot be deleted. Renaming it gets both out of the way at once.

  1. Step 1: Rename the folder

    In your host's file manager or over SFTP, rename wp-content/upgrade to wp-content/upgrade-old. Over SSH:

    bash
    mv wp-content/upgrade wp-content/upgrade-old
  2. Step 2: Install or update again

    Do it the way you tried before. WordPress makes a new wp-content/upgrade as it goes. With WP-CLI, for an update:

    bash
    wp plugin update plugin-slug
  3. Step 3: Delete the old folder

    Once the install has gone through:

    The first line gives you back permission to write to folders that had lost it, without which the second cannot empty them. If it answers "Operation not permitted", the folder belongs to another user. It does no harm where it is, and the host can remove it.

    bash
    chmod -R u+w wp-content/upgrade-old
    rm -r wp-content/upgrade-old

If the rename itself is refused, or the next attempt names wp-content/upgrade again, WordPress may not write to wp-content. That is ownership: go to the last fix.

To undo it: Delete the new wp-content/upgrade folder and rename wp-content/upgrade-old back to wp-content/upgrade.

Check the disk and the account for room

  • Takes care
  • Low risk
  • About 20 minutes

Before it unpacks a plugin or a theme, WordPress checks for free space only when the work runs from its scheduler, as automatic updates in the background do. A shortage is then reported as "Could not copy files. You may have run out of disk space." When you install or update a plugin or a theme yourself, there is no such check. The unpacking runs until the server refuses a folder or a file, and then prints "Could not create directory." or "Could not copy file."

  1. Step 1: Check how full the account is

    Your hosting panel shows how much of your disk allowance is used. If it also shows a count of files, which it may call inodes, check that too. A limit on the number of files can be reached while there is space left.

  2. Step 2: Or check from the command line

    Over SSH, from the folder WordPress is installed in. The first command shows space, the second inodes.

    df reports on the file system the folder is on. An allowance set for your account is shown in the hosting panel, so on shared hosting check there as well.

    bash
    df -h wp-content
    df -i wp-content
  3. Step 3: Remove what you no longer need

    Look first at backup archives kept on the server, old log files and copies of the site left over from a move. Download anything you might want before you delete it.

  4. Step 4: Install again

    If the panel shows room and the message stays, go back to the listing in the first fix.

Put the folder back in the right hands

  • Advanced
  • Back up first
  • About 30 minutes

Who can correct ownership depends on the hosting.

  1. Step 1: On shared or managed hosting, ask the host

    Changing a file's owner is the host's job there. Send them the full message with its path, and the line for that folder from the listing in the first fix. Ask them to give the site's files, that folder included, back to your account.

  2. Step 2: On a server you administer, correct the owner

    As the server's administrator, give the folder the owner and group the rest of the site's files have. The listing shows them. With those in place of example:example, and the folder from the message in place of wp-content/upgrade:

    bash
    chown -R example:example wp-content/upgrade
  3. Step 3: Run WP-CLI as the user the site belongs to

    A folder made by a command run as root belongs to root, and PHP cannot write inside it. WP-CLI stops when it is run as root unless it is given --allow-root, and its own warning gives the form to use instead, with the site's user in place of USER:

    bash
    sudo -u USER -i -- wp plugin install plugin-slug
  4. Step 4: If wp-config.php forces direct writing

    Before it installs anything, WordPress writes a test file into wp-content and compares its owner with the owner of WordPress's own files. If they match, it writes directly. If they do not, or the test file could not be written, it shows a form headed "Connection Information" and asks for FTP details. Setting FS_METHOD to direct skips the test. It does not change what PHP is allowed to write, so the install is refused with "Could not create directory." where the form would have been.

    Correct the ownership as above, so that the test passes by itself. Then take the line out of wp-config.php, by hand or with WP-CLI:

    WordPress's documentation says the direct method is chosen automatically when it is appropriate. Until the ownership is put right, WordPress shows the form again, and the details of your FTP account let it write as the account that owns the files.

    bash
    wp config delete FS_METHOD

WP-CLI always writes directly and never shows the form. Run by a user who may not write to the folder, it prints this message where the dashboard would have asked for FTP details.

When to get help

If the folders belong to the right user, can be written to and have room, and the message stays, the refusal comes from somewhere a listing of owners and modes does not show. Finding it takes access to the server's configuration and its logs. The same is true when the host says ownership is correct and installs still stop here.

Common questions

Is it safe to delete wp-content/upgrade?

Yes, while no install or update is running. It is WordPress's working folder. WordPress empties it before each unpack and makes it again when it is missing. That is also why deleting it rarely cures anything: it helps only when WordPress could not write to the folder or clear it.

Should I set the folder to 777?

No. If the folder belongs to the user PHP runs as, 755 already lets WordPress write. If it does not, the cure is ownership, and 777 hands the folder to every account on the server. See WordPress file permissions.

One plugin fails with this message and others install. Why?

Look at the path. WordPress names its working folder after the download, so a folder left in wp-content/upgrade by an earlier attempt at the same plugin, and which WordPress cannot delete, stops that plugin and no other. The fix for the working folder clears it. If the path is in wp-content/plugins and the message is "Destination folder already exists." instead, that page has the answer.

Is "Unable to locate WordPress content directory (wp-content)." the same fault?

No. WordPress prints that when it connects to the site over FTP or SSH and cannot find wp-content from where that account lands. A site that writes directly never shows it. WordPress's documentation gives constants for wp-config.php that name the paths, FTP_BASE and FTP_CONTENT_DIR.

Uploading the .zip fails with a different message. Where do I look?

"Missing a temporary folder." is PHP's own upload folder, covered in its own page. A site stuck on a one-line maintenance notice after an update stopped is covered in "Briefly unavailable for scheduled maintenance", and the runbook for a failed update puts the rest in order.

More on this subject

Would you rather we fixed it?

Quick Fix is $49. One issue, one site, up to about an hour. No fix, no fee. 30-day warranty. It starts with a free diagnosis.