"The uploaded file could not be moved to wp-content/uploads/YYYY/MM"

When you upload media (Media Library, a plugin upload that extracts into uploads/, or activating a plugin that drops files there), WordPress shows:

The uploaded file could not be moved to wp-content/uploads/2026/04.

The path in the error follows the current year and month. It affects images, PDFs, and anything else that lands in the uploads folder.

Why WordPress shows this

WordPress tried to call PHP's move_uploaded_file() to write the incoming file into wp-content/uploads/<YYYY>/<MM>/. The move failed because the web-server user — www-data on Apache/Nginx, apache on some RHEL-family hosts, or custom on shared hosts — does not have write permission on the uploads directory.

More commonly, a parent directory in the path is owned by root and not writable by the web-server user, so WordPress cannot create the month folder in the first place.

Root cause

One of the following, in decreasing order of likelihood:

  1. Parent wp-content/uploads/ is owned by root — usually because someone ran a setup step as root that mkdir'd into the path (a manual docker exec, a deployment script, or an unzip as root). The subsequent chown only touched specific subfolders and missed the parent.
  2. Permissions too restrictive750 or 755 with a mismatched group, so the web-server user cannot write.
  3. Ownership drift after a migration — files restored from backup as root and never re-chown'd.
  4. Rare: SELinux or AppArmor denying the write despite Unix permissions looking correct.

How to fix

On a shell with sudo access, or inside the Docker container as root:

# Adjust the path if your WP root is elsewhere
cd /var/www/html

# Make the web-server user the owner of the entire uploads tree
chown -R www-data:www-data wp-content/uploads

# Make sure uploads is group-writable
chmod -R 775 wp-content/uploads

Notes:

  • Replace www-data:www-data with the correct user on your host. Check via:
    ps aux | grep -E "apache|nginx|httpd" | head
    
    Look at the column showing the user.
  • On managed hosts you usually don't have shell access. File a ticket saying "please reset ownership on wp-content/uploads/ to the web user." They know this one.
  • Do not chmod 777. It works but is a security smell — 775 with correct ownership is the right fix.

After the change, retry the upload. It should go through without a restart.

How to confirm this is your problem

From a shell, check ownership of the uploads path:

ls -ld wp-content/uploads wp-content/uploads/2026 wp-content/uploads/2026/04

If you see root root on any of them, or a user other than your web-server user, that's the cause. After the fix, the listing should show www-data www-data (or your host's equivalent) end-to-end.

Why this happens on fresh installs and not migrations

Official WordPress installers create uploads/ lazily — the directory exists, but year/month subdirectories are created on first upload. If the install or any post-install step ran as root before the first upload, the parent is root-owned and the web-server user cannot write the child.

A migration from a working host usually carries correct ownership with it, which is why fresh installs are disproportionately affected.

Still stuck?

If ownership looks correct and the error persists, the cause is likely SELinux or AppArmor. Contact support@wpproconverter.com with the output of ls -ld wp-content/uploads and your host type.