Driver FixRecommendedSound, Wi-Fi or graphics acting up? Check drivers firstFind missing or outdated drivers fast.Check DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan Now×
Skip to content
World desk11 min

How to Fix WordPress Multisite Media Upload Permission Errors

A practical, security-conscious guide to Multisite media upload failures, from site-specific upload paths and PHP ownership to network limits, capabilities, Apache/Nginx rules, and legacy routing.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

If media uploads work on your main WordPress site but fail on a subsite, check the subsite’s actual upload directory first. Multisite sites usually write to different paths, and the PHP/web-server account must be able to traverse and write that specific directory. Then check network upload limits, the uploader’s role, and your Apache or Nginx routing. Do not “fix” the problem with chmod 777; WordPress warns that permissions that are too broad can allow attackers to upload malicious files or alter executable code.

What the error usually means

Typical messages include “The uploaded file could not be moved to wp-content/uploads,” “Unable to create directory,” “Sorry, you are not allowed to upload this file type,” or a failed request with an HTTP 403 status. They do not all indicate the same fault.

As an Amazon Associate I earn from qualifying purchases.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • A move, create-directory, or permission-denied message usually means that the account running PHP cannot reach, write to, or rename files in the destination directory.
  • A 403 can indicate web-server or security-policy denial before WordPress finishes processing the upload.
  • An “invalid file type” message points to a network MIME restriction, not necessarily a filesystem problem.
  • An upload that works for the network’s first site but not a subsite often targets a different directory or a different rewrite rule.

WordPress’s file-permissions guidance states: “So if you set the permissions too low, then your server won’t be able to access the file and will cause an error.” The practical implication is to identify the exact site-specific path and PHP execution account before changing anything.

Understand where each Multisite site stores uploads

Multisite does not put every site’s files in one identical directory. The normal layout depends on the site’s position in the network and on whether the network uses the current or legacy storage scheme.

Network layout Typical location What to check
First site in a modern network /wp-content/uploads/ Confirm the directory exists and is writable by the PHP/web-server account.
Later sites in a modern network /wp-content/uploads/sites/<site-number>/ Replace <site-number> with the affected site’s numeric ID; do not assume the main site’s directory is sufficient.
Legacy Multisite network wp-content/blogs.dir/ with files routed through /files/ Check both the legacy directory and the rewrite or location rule that serves /files/.

The site ID is not the same as a username or domain name. In Network Admin, open the Sites list, select the affected site, and note its numeric ID. A subsite with ID 3, for example, commonly uses /wp-content/uploads/sites/3/ in a modern network. A custom upload-path filter, migration, or old installation can change that convention, so verify the path rather than inferring it solely from the ID.

Use a safe diagnostic sequence

Work through these checks in order. Record the exact error, HTTP status, filename, site ID, and time of each test so that a host or administrator can correlate the request with server logs.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  1. Reproduce the failure on the affected site. Sign in to the subsite, open Media > Add New, and upload a small image such as a permitted JPEG or PNG. Capture the complete on-screen message and browser-network status.
  2. Confirm the site and path. In Network Admin > Sites, identify the site ID. Determine whether the network uses modern uploads/sites/<id> storage or legacy blogs.dir//files/ routing. Compare the configured path with the directory that actually exists on disk.
  3. Check the directory and its parents. On the server, inspect the destination and every parent directory. A writable final directory is useless if PHP cannot traverse /wp-content or /wp-content/uploads.
  4. Identify the PHP execution account. It may be a PHP-FPM pool user, an Apache worker account, or a host-specific service account. Check the pool or virtual-host configuration rather than assuming a name such as www-data.
  5. Verify ownership before modes. Make the affected directory owned by the account or group that actually runs PHP, subject to your host’s deployment policy. Correct ownership first; a permissive mode cannot reliably compensate for an incorrect owner, ACL, container mount, or security policy.
  6. Review upload limits and capabilities. Check Network Admin limits and the uploader’s role before making additional filesystem changes.
  7. Validate web-server routing. Confirm the Apache or Nginx Multisite rules match the network type and WordPress version.
  8. Retest with a small allowed image. If it still fails, inspect PHP-FPM, web-server, WordPress, and operating-system security logs for the same timestamp.

Check ownership, traversal, and write access

Inspect without changing anything

From the WordPress document root, inspect the path and each parent directory. Commands such as these provide evidence without altering files:

namei -l /var/www/html/wp-content/uploads/sites/3
ls -ld /var/www/html/wp-content 
       /var/www/html/wp-content/uploads 
       /var/www/html/wp-content/uploads/sites 
       /var/www/html/wp-content/uploads/sites/3
stat /var/www/html/wp-content/uploads/sites/3

Replace the example path with the real document root and site ID. Look for a missing directory, an owner unrelated to the PHP account, a group that the process cannot use, or a parent directory lacking execute (traversal) permission. On systems using ACLs, inspect ACL entries as well as the traditional owner/group/mode fields.

Create the directory only when it is genuinely missing

If the expected directory does not exist, create it through your normal deployment or server-administration process, then assign ownership and access according to the PHP pool and host policy. Do not create a world-writable directory as a shortcut. A migration may also have left the directory on a different volume or container mount; verify that the path belongs to the active web server, not merely to a shell account on another host.

Apply the narrowest workable modes

There is no single safe numeric mode for every hosting stack. A common arrangement is owner and group access for the PHP/web-server account, with directories traversable by the process and files writable only where WordPress needs to create or update them. Some hosts use directory mode 755 and file mode 644; others require group-based 775 because deployments and PHP share a group. Treat those as examples to validate, not universal prescriptions. WordPress specifically warns that overly broad permissions can let an attacker upload malicious files or modify executable code. Never use chmod -R 777 as a blanket repair.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Check Network Admin upload limits and file types

Multisite can reject an upload before WordPress attempts to move it into the destination directory. In Network Admin > Settings, review the network’s maximum upload size and the allowed upload file types. The exact labels can vary by WordPress version, but the settings govern the network rather than one subsite.

  • Compare the file size with the network maximum and with PHP limits such as upload_max_filesize and post_max_size. The smallest applicable limit wins.
  • Check the filename extension and MIME type. A file renamed from one extension to another can still be rejected because its detected type is not allowed.
  • Retest with a small, ordinary image after changing a limit. If that succeeds while the original file fails, the directory was probably not the primary fault.

Do not loosen the network’s allowed types merely to bypass a message. Permit only the formats the network’s administrators can safely handle, and investigate unusual MIME reports rather than trusting an extension alone.

Verify the uploader’s role and capabilities

A subsite administrator is not equivalent to the administrator of a single-site WordPress installation. Multisite separates site-level administration from network-wide authority. A user who can manage one site may still be unable to perform an operation reserved for a Super Admin.

WordPress documents the relevant unfiltered-upload rule this way: “With this constant defined, all roles on a single site install can be given the unfiltered_upload capability, but only Super Admins can be given the capability on a Multisite install.” If a workflow requires uploads that bypass normal MIME filtering, review the ALLOW_UNFILTERED_UPLOADS configuration and the Super Admin restriction. Do not weaken filesystem permissions to compensate for a capability decision.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Distinguish a capability failure from a filesystem failure

  • If the interface says the file type is not permitted, test the network MIME settings and the user’s capability.
  • If the interface says the file cannot be moved or a directory cannot be created, inspect ownership, traversal, storage, and server policy.
  • If the same user can upload an ordinary image to one site but not another, compare the two sites’ IDs, paths, and routing rules before changing the role.

Fix Apache Multisite routing

Apache networks depend on mod_rewrite and on override settings that allow the Multisite rewrite rules to operate. If .htaccess is ignored, WordPress may generate URLs that do not map to the stored files, or requests to legacy /files/ paths may return errors.

  • Confirm that mod_rewrite is loaded for the active Apache virtual host.
  • Check the document root’s AllowOverride setting. It must permit the categories of directives used by the network’s .htaccess; a server set to AllowOverride None will ignore them.
  • Compare the current Multisite rules with the network type: subdirectory and subdomain installations use different rewrite details.
  • After changing Apache configuration, reload the service through the host’s approved process and retest both the main site and the affected subsite.

Do not copy rewrite rules from an unrelated network type or an old installation. A rule that appears to fix one URL can break administrator requests or route another site’s files incorrectly.

Fix Nginx Multisite routing

Nginx does not read .htaccess. Every Multisite rewrite and static-file rule must therefore be present in the Nginx server configuration. The correct rules depend on whether the network uses subdomains or subdirectories, whether it is a modern or legacy network, and which WordPress version generated the configuration.

  • Confirm that the active server block points to the real WordPress document root.
  • Install the matching Multisite rules for the network type, including handling for /files/ and blogs.dir on legacy networks.
  • Ensure that the PHP location passes requests to the same PHP-FPM pool whose account owns or can write the upload directory.
  • Run the configuration test supplied by your distribution before reloading Nginx, then retest an image upload and its public URL.

An Nginx configuration can allow the upload request to reach PHP while still serving the resulting file from the wrong location. Test both operations: upload the file and open the generated media URL from the subsite.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Handle legacy blogs.dir and /files/ networks

Older Multisite networks may store site files under wp-content/blogs.dir and expose them through /files/ routing. WordPress’s file-permissions guidance specifically notes that a Multisite installation may need the same attention in wp-content/blogs.dir/ as in wp-content/uploads/.

For such a network, check the numeric blog directory, its owner, and the rewrite or Nginx location that maps /files/ to it. A directory that is writable but not routed will produce a different symptom from a directory that PHP cannot write: the upload may complete, yet the image URL returns 404 or 403. Preserve the legacy layout during diagnosis; migrating storage is a separate change that should be planned and tested with backups.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Investigate failures that are not fixed by permissions

Temporary upload directory

PHP first places an upload in its temporary directory before WordPress moves it into the site’s media directory. Check the PHP setting for the temporary upload directory, its existence, free space, ownership, and security policy. A failure there can look like a destination-permission error.

Disk space, inode limits, and quotas

Check free bytes and inodes on the filesystem that contains both the temporary directory and the WordPress directory. Hosting quotas can reject a new file even when Unix permissions look correct.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

SELinux or AppArmor

Mandatory access-control policies can deny writes despite apparently correct owner and mode values. Review audit logs at the time of the failed request and apply the host’s documented policy change rather than disabling the protection globally.

Container and shared-storage mounts

In containers or clustered hosting, the PHP process may see a different mount or UID mapping from the shell session used for inspection. Verify the path from inside the PHP container or the node serving the request, and check shared-storage locking and read/write mounts.

Plugins and custom code

A security, media, image-optimization, or storage plugin can filter upload MIME types, alter the upload path, or block requests. Reproduce the issue with such plugins disabled only in a controlled staging environment or during a maintenance window. Record which plugin or filter changes the result before re-enabling components one at a time.

Use the error and status code to choose the next check

Observed symptom Most useful first check What confirms the diagnosis
“The uploaded file could not be moved” Destination path, parent traversal, owner, and PHP write access Logs show a failed rename or move_uploaded_file at the site-specific path.
“Unable to create directory” Missing directory, parent ownership, ACLs, and disk space The PHP account cannot create a test directory in the affected location.
HTTP 403 during upload Apache/Nginx rules, Web Application Firewall, and security-policy logs The server or policy log identifies the denied request or path.
“File type not permitted” Network allowed types and uploader capability A small file with an allowed MIME type succeeds for the same user.
Upload succeeds but media URL is 404 or 403 Rewrite/location rules and legacy /files/ mapping The file exists on disk, but the web server maps its URL elsewhere or denies it.
Only large files fail Network maximum, PHP size limits, proxy limits, and timeouts A small permitted image succeeds while a file above one limit fails.

Retest and verify the complete path

After each targeted change, repeat the same controlled test rather than uploading an arbitrary large file. Use a small JPEG or PNG that the network permits, upload it from the affected subsite, confirm that WordPress creates the expected year/month directory, and open the generated media URL in a private browser window. Then test the main site to ensure that a rewrite or ownership change did not break another site.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Keep the timestamp, site ID, filename, HTTP status, and the exact server change in your change record. If the test still fails, provide those details and the relevant PHP-FPM, Apache/Nginx, WordPress, and security-policy log entries to the person administering the host. Avoid repeated recursive permission changes: they can obscure the original cause and widen the attack surface.

Prevent the problem on future sites and migrations

  • Document the network type, WordPress version, PHP-FPM account, document root, and upload-storage convention.
  • When creating a site, verify its numeric ID and confirm that its modern uploads/sites/<id> directory is created with the expected owner and group.
  • Keep Network Admin’s maximum size and allowed MIME list aligned with PHP and proxy limits, and review them after server migrations.
  • Test both subdirectory and subdomain URLs, including the media URL generated after an upload.
  • Monitor disk space, inode usage, quotas, and PHP temporary-storage health.
  • Back up the database and upload directories before changing legacy routing or moving media storage.
  • Use least-privilege service accounts and review ACL, SELinux, or AppArmor changes as part of deployment.

When to involve your host or server administrator

Escalate when you cannot identify the PHP account, do not control Apache/Nginx, share storage across nodes, or see denials in SELinux, AppArmor, a Web Application Firewall, or a hosting quota system. The administrator will need the affected site ID, exact path, timestamp, HTTP status, filename, and log excerpt. A managed WordPress or server-administration team is appropriate when the fix crosses filesystem ownership, PHP execution context, and web-server configuration; changing only the WordPress dashboard settings cannot repair those layers.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.