Fixing the Failed to Write File to Disk Upload Error
PHP started writing the upload to its temporary folder and ran out of room partway through. The disk that is full is usually the temporary partition, not the one your uploads folder sits on, which is why freeing space in wp-content often changes nothing.
PHP created the temporary file for your upload but could not finish writing it, almost always because the partition it was writing to ran out of space. "Failed to write file to disk." is how WordPress words PHP's upload error code 7, UPLOAD_ERR_CANT_WRITE. The upload was cut off before WordPress received it. The full partition is the one holding PHP's temporary directory, which is often not the one holding your site.
Which stage failed
An upload in WordPress passes through four stages, and each one has its own message:
- PHP receives the request and writes the file to its temporary directory. Failures here come back as PHP error codes: Missing a temporary folder when the temp file cannot be created (code 6), and this error when it cannot be written (code 7).
- WordPress checks the file for size, type and the form action, then calls
wp_upload_dir(). If the year/month folder cannot be created, you get Unable to create directory. - WordPress moves the file from the temp directory into
wp-content/uploadswithmove_uploaded_file(). If that fails, the message is could not be moved to wp-content/uploads. - WordPress builds the image sizes. If the server crashes or runs out of memory here, the error is the image post-processing message.
Code 7 belongs to stage 1. No WordPress setting, plugin or uploads-folder permission affects it, because none of them come into play until PHP has finished.
Step 1: find where PHP writes temporary files
<?php
// tmp-check.php — load it in the browser once, then delete it.
header( 'Content-Type: text/plain' );
$dir = ini_get( 'upload_tmp_dir' ) ?: sys_get_temp_dir();
echo "temp dir: $dir\n";
echo 'free: ', round( disk_free_space( $dir ) / 1048576 ), " MB\n";
echo 'upload_max_filesize: ', ini_get( 'upload_max_filesize' ), "\n";
Run it through the web server. The command-line PHP may use another configuration, and under systemd PHP-FPM may run with PrivateTmp, which gives it its own /tmp.
Step 2: check space, inodes and the filesystem type
df -h /tmp
df -i /tmp
findmnt -T /tmp
Look for three things:
- Use% at or near 100%. Something has filled the temp partition: abandoned session files, a backup plugin that stages archives in
/tmp, an image optimiser that left work files behind, or log files. - A tmpfs mount.
findmntshowstmpfswhen/tmplives in RAM. Its size is often set to a fraction of memory, and a few large uploads at once can fill it. - An account quota. On shared hosting the temp directory may count against your quota, and the account can be at its limit even when the server has space. The hosting panel's disk usage page, or
quota -swhere it exists, shows this.
Step 3: free space or move the temp directory
Clearing old files is the quick fix:
find /tmp -type f -user www-data -mtime +2 -delete
Run this as the PHP user, or change the user to match, and never delete files that belong to running processes owned by other users. If the partition is simply too small for the files you upload, point PHP at a directory on a larger partition:
; php.ini or PHP-FPM pool (php_admin_value[upload_tmp_dir])
upload_tmp_dir = /var/lib/php/uploads
upload_tmp_dir cannot be changed from .htaccess, .user.ini or wp-config.php. The directory has to exist, be writable by the PHP user, and be allowed by open_basedir if that is set. Reload PHP-FPM or Apache afterwards.
The web server buffers the upload first
Nginx writes large request bodies to its own temporary directory, client_body_temp_path, before handing them to PHP. If that partition is full, nginx fails the request itself, with a 500 error and a "No space left on device" entry in its error log, and the WordPress message never appears. If you have both, free space in both places. They are often the same /var partition.
When the disk is not full
Code 7 is reported on any failed write, so a few rarer causes produce it too:
- A read-only filesystem. After an I/O error the kernel can remount a partition read-only, and every write fails.
dmesgandgrep ' ro,' /proc/mountsshow it, and this is a job for the host. - A security module. SELinux or AppArmor rules on a custom temp directory usually block creating the file, which gives Missing a temporary folder instead, but check the audit log after a failed upload.
- Antivirus scanning on upload. On some hosts a scanner that hooks file writes may abort the ones it flags. Upload a plain text file to rule this out.
Common mistakes
- Freeing space in
wp-contentand expecting uploads to work. The temp partition is usually somewhere else. - Raising
upload_max_filesize. That limit produces a different message, explained in upload_max_filesize, and raising it lets even larger files fill the partition. - Treating it as a WordPress bug and reinstalling core. Nothing in WordPress runs until the write is complete.
- Deleting files in
/tmpthat belong to other services. Only remove the PHP user's old files, and only when nothing is using them.
Verify
df -handdf -ion the temp directory show free space and inodes.- Upload a file close to your usual maximum size in the Media Library and in the block editor.
- Upload several at once. A tmpfs that only just fits one file will fail on a batch.
- Watch disk use over a few days. If it fills up again, find what writes to the temp directory and stop it there.
Frequently asked
- The panel usually reports your account's home partition. PHP writes uploads to its temporary directory first, and that is often /tmp on a separate, much smaller partition or a RAM-backed tmpfs. That partition can be full while the one holding wp-content is nearly empty.
- It may look like one, but size limits produce a different message, such as one naming upload_max_filesize or saying the file exceeds the maximum upload size for this site. Failed to write file to disk on large files only means the temporary partition has some room but not enough for the whole file.
- No. The failure happens while PHP writes its own temporary copy, before WordPress touches wp-content/uploads. Permission problems on the uploads folder produce could not be moved or unable to create directory instead.