File upload fails with failed to open stream or move_uploaded_file: the causes, in order

The file reaches the server, PHP stores it in a temporary folder and your code tries to move it to its final place with move_uploaded_file(). If that step fails, the warning is “failed to open stream: Permission denied”, “No such file or directory” or “Unable to move”. It is not a size problem (for that there is uploading large files in PHP), it is a problem of path, permissions or space. There is a way to see the cause: the error code in $_FILES.

Reading the upload error code

Before moving the file, PHP leaves a number in $_FILES['field']['error']. Print it on a test page, or write it to the error log.

Code Means What to do
0 The upload went fine. If it still fails, the problem is the next step: moving the file.
1 Larger than PHP’s limit. See upload_max_filesize and post_max_size.
2 Larger than the form’s own limit. Look for a hidden MAX_FILE_SIZE field in the form.
3 Only part of it arrived. Connection dropped. Try again on a better network.
4 No file was sent. Check the form has enctype="multipart/form-data". Without it $_FILES arrives empty.
6 The temporary folder is missing. Ask us for help: it is the server’s.
7 Could not write to disk. It may be the account’s space used up. Check the counter in cPanel.
8 A PHP extension stopped the upload. Ask us for help with the address and the time.

If the code is 0 and moving fails

1 Does the destination folder exist? “No such file or directory” is almost always a wrong path. A relative path changes depending on which file calls it. Prefer a full path built from __DIR__.
2 Does the folder accept writing? In general the folder should belong to your account and have permission 755 (and files 644). “Permission denied” on a folder you just created, or one made by another user (on a VPS, root), is the commonest cause. See error 403: permissions, .htaccess and blocked IPs. Do not set 777 in desperation.
3 Has the space run out? A full account disk, or the file-count limit (inodes), makes writes fail. See the limits nobody advertises.
4 Does the file name have awkward characters? Spaces, accents or an empty name cause trouble. Generate your own name (a random string plus the extension) instead of using what the user sent.
5 Read the error log: it carries the exact path that failed. See where the PHP error log is.
Be careful what you allow to be uploaded. If the destination folder is inside the site and the user can upload a .php file, whoever uploads it runs code on your server. Accept only the types you need, check the type by content (not just by extension), rename the file and, if you can, store it outside the public folder.
In WordPress the error shows as “HTTP error” or “Could not move the file”. See raising the WordPress upload limit. If the upload is very large or frequent, use SFTP: see SFTP instead of FTP.

Seen the error code and the path and it still fails? Send us the full message and the page address.

Open a support ticket

SEE ALSO

Uploading large files in PHP: upload_max_filesize and post_max_size

Error 403 Forbidden: permissions, .htaccess and blocked IPs

Where the PHP error log is

The limits nobody advertises: inodes, processes and memory

RECOMMENDED PRODUCT

Web hosting with cPanel

Domain and SSL included, daily backups and the panel you already know. from $6.60/mo (3-year plan, with coupon)

See plans
  • 0 Users Found This Useful
Was this answer helpful?