Skip to content
ThemesIonic — home
Troubleshooting

Fixing the Uploaded File Could Not Be Moved Error

The upload reached WordPress and the destination folder exists, but PHP was not allowed to put the file in it. The folder the message names is the one to inspect, and an existing folder with the wrong owner is the usual cause.

5 min read intermediate

The upload arrived and WordPress found the destination folder, but PHP was refused when it tried to put the file there. "The uploaded file could not be moved to wp-content/uploads/2026/11." comes from the last step of _wp_handle_upload(), where move_uploaded_file() returned false. The path in the message is the exact folder that refused the file, so start your checks there.

Where this fits in the upload

WordPress handles an upload in a fixed order, and each failure has its own message:

Stage What happens Error if it fails
PHP receives the file Written to PHP's temp directory Missing a temporary folder, Failed to write file to disk
WordPress checks it Size, type, then wp_upload_dir() creates the year/month folder Unable to create directory, file type not permitted
WordPress moves it move_uploaded_file() into that folder The uploaded file could not be moved to …
WordPress processes it Image sub-sizes are generated Post-processing of the image failed

Getting this far rules a lot out. PHP's temp directory works, the file type is allowed, and the destination folder exists.

Why the folder check passes and the move fails

wp_upload_dir() calls wp_mkdir_p() on the destination, and that function returns true as soon as the folder exists. It never checks whether the folder is writable. So a month folder that exists but belongs to another user passes the check, and the upload then fails on the move. This is the most common cause, and it explains the typical pattern: uploads work for months, then stop on the first of a month, or after a restore.

Step 1: compare owners

The message names a path like wp-content/uploads/2026/11. Check that folder and its parents:

ls -ld wp-content/uploads wp-content/uploads/2026 wp-content/uploads/2026/11
ps -o user= -p "$(pgrep -f 'php-fpm: pool' | head -1)"

If the folder belongs to root, or to an SFTP user that is not the PHP user, fix the ownership:

chown -R www-data:www-data wp-content/uploads
find wp-content/uploads -type d -exec chmod 755 {} \;
find wp-content/uploads -type f -exec chmod 644 {} \;

Replace www-data with the PHP user you found. Folders usually get the wrong owner from a restore run as root, a deploy script, a server cron job that writes into uploads, or someone creating the folder by hand over SFTP.

On shared hosting, PHP usually runs as your own account. If the panel's file manager shows a different owner on a folder, ask the host to reset it. You may not be able to change it yourself.

If wp-content/uploads is a symlink to shared or mounted storage, the real target has to be inside open_basedir. If it is not, PHP refuses to touch it. Depending on which check hits first, you get this message or Unable to create directory, and because WordPress calls move_uploaded_file() with @, the open_basedir restriction in effect warning may never reach the log. Add the target path to open_basedir in the PHP-FPM pool or php.ini, or mount the storage inside the site's own directory tree.

Network mounts (NFS, SMB, FUSE-based object storage) can also map the PHP user to a different account on the remote side. A folder that looks writable in ls can still refuse writes there. Test it directly:

sudo -u www-data touch wp-content/uploads/2026/11/write-test && echo ok

Step 3: space on the uploads partition

When PHP's temp directory and wp-content are on different filesystems, the move is really a copy. If the uploads partition or the account quota is full, the copy fails and you get this message, not a disk error. df -h wp-content/uploads and the hosting panel's quota page will show it.

Step 4: plugins that take over the move

WordPress has a pre_move_uploaded_file filter. Plugins that offload media to cloud storage use it to replace the move entirely. If a plugin like that is half-configured, deactivate it and upload again. If the upload then works, the problem is in the plugin's storage settings, not in the server.

The path in the message

WordPress shortens the destination before printing it. If the uploads folder is inside the WordPress install, the path is shown relative to it, starting with wp-content/. If it is outside, only the folder name and the year/month part are shown, such as uploads/2026/11. A message without the wp-content/ prefix on a normal install suggests that upload_path or the UPLOADS constant points somewhere else. That often happens after moving to a new host. wp option get upload_path shows the stored value.

Common mistakes

  • Running chmod -R 777 on the uploads folder. It may make the error go away, but it lets other accounts on the server write files to your site.
  • Fixing only the top uploads folder when it is the month folder that has the wrong owner.
  • Assuming the folder is fine because older images still load. Reading a file needs far less permission than writing one.
  • Reinstalling WordPress or deactivating every plugin first. Unless a media offload plugin is involved, neither touches the folder that refused the file.

Verify

  • sudo -u <php-user> touch works in the folder the message named.
  • An upload in the Media Library and in the block editor lands in the current month's folder.
  • The new file is owned by the PHP user, so next month's folder will be created by the same user.
  • If images also fail to appear after upload, check images not showing. That is a URL problem, not a write problem.

Frequently asked

WordPress only checks that the destination folder exists. If the year/month folder is already there, the check passes even when PHP cannot write into it, and the failure surfaces one step later when the file is moved. Unable to create directory appears only when the folder is missing and cannot be made.
Each month gets a new folder, created by whoever uploads first. If a cron job, a backup restore or an SFTP session created this month's folder as a different user, PHP cannot write into it. Last month's folder still works, which makes the problem look random.
It hides the symptom by letting every account on the server write there. Give ownership to the user PHP runs as and use 755 for folders and 644 for files instead. On shared hosting that user is usually your own account.

Related guides