Fixing the Missing a Temporary Folder Upload Error
The message is PHP's, not WordPress's: PHP could not create the temporary file an upload is written to before any WordPress code runs. The fix lives in PHP's configuration, which is why WP_TEMP_DIR does nothing for it.
PHP could not create the temporary file it writes every upload to, so the file never reached WordPress. "Missing a temporary folder." is WordPress's wording for PHP's upload error code 6, UPLOAD_ERR_NO_TMP_DIR. WordPress did not fail here; it read the error PHP attached to the upload and printed the matching sentence. That changes where you look: the fix is in PHP's configuration and the server's disk, not in WordPress settings or plugins.
Where the message comes from
When a browser posts a file, PHP streams it into a temporary file before your code runs, then fills $_FILES with the name, the temporary path and an error code. WordPress's upload handler, _wp_handle_upload(), checks that code early and maps it to a fixed list of sentences:
| Code | Constant | WordPress message |
|---|---|---|
| 1 | UPLOAD_ERR_INI_SIZE |
The uploaded file exceeds the upload_max_filesize directive in php.ini. |
| 3 | UPLOAD_ERR_PARTIAL |
The uploaded file was only partially uploaded. |
| 6 | UPLOAD_ERR_NO_TMP_DIR |
Missing a temporary folder. |
| 7 | UPLOAD_ERR_CANT_WRITE |
Failed to write file to disk. |
| 8 | UPLOAD_ERR_EXTENSION |
File upload stopped by extension. |
Codes 6 and 7 are neighbours and are easy to confuse. Code 6 means PHP could not create the temporary file at all. Code 7 means it created the file but the write failed partway through, which is covered in Failed to write file to disk. If the upload got past this stage and failed later, you will see could not be moved or unable to create directory instead. Those are about the uploads folder, and this error is not.
In the block editor the same sentence comes back from the REST API as rest_upload_unknown_error with status 500. The text matches, and so does the cause.
Step 1: find the directory PHP is using
Ask PHP itself rather than guessing. Put a temporary file in the site root, load it once, then delete it:
<?php
// tmp-check.php — delete after use.
header( 'Content-Type: text/plain' );
echo 'upload_tmp_dir: ', var_export( ini_get( 'upload_tmp_dir' ), true ), "\n";
echo 'sys_get_temp_dir: ', sys_get_temp_dir(), "\n";
echo 'open_basedir: ', var_export( ini_get( 'open_basedir' ), true ), "\n";
echo 'file_uploads: ', ini_get( 'file_uploads' ), "\n";
Run it through the web server, not on the command line. The CLI often reads a different php.ini, so it can report a perfectly healthy temp directory while PHP-FPM uses a broken one.
If upload_tmp_dir is empty, PHP uses the system temp directory, usually /tmp. If it names a directory that is missing or not writable by the PHP user, PHP falls back to the system temp directory, so the error appears only when that fallback fails too.
Step 2: check that directory on the server
ls -ld /path/from/step-1
df -h /path/from/step-1
df -i /path/from/step-1
Three results produce this error:
- The directory does not exist. A custom
upload_tmp_dir, such as/home/user/tmp, was deleted, or never created on a new server, and the fallback to the system temp directory failed as well, usually because ofopen_basedir(step 3). - PHP cannot write to it. Wrong owner, or a mode that leaves out the PHP user.
/tmpitself should bedrwxrwxrwt(1777). - No inodes left. A partition with free space but no free inodes cannot create even an empty file. Session files and cache fragments that pile up in
/tmpare the usual cause, anddf -halone will not show it.
Step 3: open_basedir
If open_basedir is set and leaves out the system temp directory, PHP is not allowed to use it when upload_tmp_dir is empty or unusable, and the upload fails the same way. Control panels that set open_basedir per account normally include a private tmp folder. Moving the site, or editing the list by hand, is how that entry goes missing. Add the temp directory to the list, or point upload_tmp_dir at a directory that is already in it.
Step 4: set upload_tmp_dir where PHP will read it
upload_tmp_dir is a system-level setting. PHP silently ignores it in .htaccess, .user.ini and ini_set(), which is why copied snippets so often appear to do nothing. It works in these places:
; php.ini
upload_tmp_dir = /var/lib/php/uploads
; PHP-FPM pool, e.g. /etc/php/8.3/fpm/pool.d/www.conf
php_admin_value[upload_tmp_dir] = /var/lib/php/uploads
Create the directory with the right owner, then reload PHP-FPM or Apache:
mkdir -p /var/lib/php/uploads
chown www-data:www-data /var/lib/php/uploads
chmod 700 /var/lib/php/uploads
systemctl reload php8.3-fpm
Use the user and service name from your own server. On shared hosting, look for the temporary directory option in the panel's PHP settings, or ask the host. This is a server setting you may not have access to.
The WP_TEMP_DIR trap
The most common advice for this error is to add a line to wp-config.php:
define( 'WP_TEMP_DIR', ABSPATH . 'wp-content/temp/' );
It does not help here. WP_TEMP_DIR only changes what get_temp_dir() returns, and WordPress calls that function for files it creates itself: plugin and theme packages during updates, remote files fetched by download_url(), and raw-body uploads to the REST API. A normal media upload is written to disk by PHP before wp-config.php is even read. The constant is a good fix for "Download failed" during updates, which is a different problem.
Common mistakes
- Testing with
php -ion the command line instead of through the web server. - Running
chmod 777on the uploads folder. This error never reaches the uploads folder. - Setting
upload_tmp_dirin.user.iniand assuming it took effect. Check it with the script from step 1. - Mistaking this for a size limit. Size problems give code 1 or 2, and upload_max_filesize is a separate fix.
Verify
- The script from step 1 shows the directory you expect, then is deleted.
- Media › Add New accepts a small image and a larger one.
- Upload once in the block editor too, since it uses the REST API rather than
async-upload.php. - The PHP error log no longer shows
File upload error - unable to create a temporary file. Turn on debug logging if you cannot see the server log.
Frequently asked
- Because PHP stores an uploaded file before WordPress loads, using its own upload_tmp_dir setting. WP_TEMP_DIR only changes where WordPress itself creates temporary files, such as plugin and theme downloads. It cannot affect a decision PHP made before wp-config.php was read.
- No. upload_tmp_dir is a system-level setting, so PHP ignores it in .htaccess, .user.ini and ini_set(). It has to go in php.ini, in a PHP-FPM pool as php_admin_value, or in the Apache virtual host. On shared hosting that means the control panel's PHP settings or a support ticket.
- The temporary folder is usually shared with the rest of the server. A cleanup job that removed it, a full partition, exhausted inodes, or a host-side PHP upgrade that reset upload_tmp_dir all produce the same error on a site nobody touched.