You drop an image or plugin ZIP into your WordPress admin, and the media uploader immediately barfs: Upload: Failed to write file to disk. It’s an annoying error because WordPress doesn’t tell you why it failed to write. Here’s how to trace the underlying PHP upload breakdown, fix permissions in Hostinger hPanel, set up a dedicated temp directory, and clear out inode limits.

Why WordPress Fails to Write Uploads to Disk
PHP handles uploads in two stages. When you upload a file in WordPress, PHP first saves it to a temporary directory on the server (set by upload_tmp_dir). Once that file is verified, WordPress uses wp_handle_upload() to move it to its permanent home inside /wp-content/uploads/YYYY/MM/.
If either step fails, PHP throws error code 7 (UPLOAD_ERR_CANT_WRITE), as detailed in the PHP file upload error constants. On Hostinger, I’ve almost always seen this boil down to one of four issues:
- Bad folder permissions: The
wp-content/uploadsfolder has the wrong permissions or ownership, so the web server can’t write to it. - Maxed-out inodes: Your Hostinger plan ran out of inodes, meaning the filesystem literally can’t create another file entry.
- Locked or missing PHP temp folder: PHP can’t write to the system
/tmppath due toopen_basedirrestrictions or a full temp partition. - Stale upload path in the database: An old site migration left a hardcoded, dead server path in your
upload_pathdatabase setting.
Step 1: Check Inode Limits and Disk Quota in hPanel
Before touching any configs, check your actual storage limits. An inode is just a data structure representing a file or directory. If your account hits 100% of its inode limit, it doesn’t matter if you still have 20 GB of free disk space—the OS will refuse to create new files.
- Log in to your Hostinger hPanel.
- Go to Hosting → Manage for your domain.
- In the left sidebar, click Plan Usage (under Performance).
- Check both Disk Usage and Inodes.
If inodes are sitting above 95% (or maxed out in red), clear out old cache files, purge old staging clones using our guide to manage WordPress staging environments cleanly, or empty your wp-content/cache directory before doing anything else.
Step 2: Reset WordPress File and Directory Permissions
WordPress expects directory permissions to be 755 and file permissions to be 644. If a botched migration or plugin update changed wp-content/uploads to 555 or messed up the ownership group, uploads instantly break.
You can fix this right in hPanel or through SSH. As noted in the WordPress file permissions documentation, don’t ever set folders to 777—Hostinger’s security layers will actively block world-writable directories.
Option A: Automated Fix via hPanel
- In your hPanel dashboard, search for Fix File Ownership.
- Check the box to reset permissions to default values.
- Click Execute. Hostinger will recursively apply
755to folders and644to files.
Option B: Manual Fix via SSH
If you have SSH enabled on your Hostinger plan, jump into your site root (usually public_html) and run:
# Navigate to the public web root
cd ~/public_html # Set all directories to 755
find wp-content/uploads -type d -exec chmod 755 {} ; # Set all files to 644
find wp-content/uploads -type f -exec chmod 644 {} ;This explicitly resets permissions just for your uploads directory without touching any custom script permissions elsewhere.
Step 3: Define a Custom WordPress Temp Directory
If your uploads folder permissions are fine but uploads still fail, the system-level /tmp directory is usually full or locked down by PHP security policies. You can bypass the shared server temp directory by telling WordPress to use a folder inside your own web root.
Open your wp-config.php file via FTP or hPanel’s File Manager, and add this right before the /* That's all, stop editing! Happy publishing. */ line:
/** Define custom upload temp directory for Hostinger */
define('WP_TEMP_DIR', dirname(__FILE__) . '/wp-content/tmp');Now create that directory so WordPress can actually use it:
- In File Manager, open
public_html/wp-content/. - Create a new folder named
tmp. - Make sure permissions on
wp-content/tmpare set to755.
WordPress will now buffer incoming files directly in your own private temp folder instead of relying on the server’s shared /tmp.
Step 4: Configure `upload_tmp_dir` in PHP Configuration
Some plugins bypass WordPress core upload helpers and use native PHP routines directly. If you have a plugin uploading files outside the standard Media Library, you’ll need to point PHP itself to your custom temp directory.
In your public_html root, open or create a .user.ini file and add:
upload_tmp_dir = /home/u123456789/domains/yourdomain.com/public_html/wp-content/tmp
upload_max_filesize = 64M
post_max_size = 64M
memory_limit = 256MMake sure to replace /home/u123456789/domains/yourdomain.com/public_html with your actual absolute path (you can grab this right from the top of the hPanel File Manager). If you’re also running into file size limits, check out our guide to increase WordPress PHP memory limit and max upload size.
Step 5: Check and Clear `upload_path` in `wp_options`
If you recently migrated your site to Hostinger from another host, your database might still have an old, hardcoded absolute path stored in upload_path. If that path doesn’t exist on Hostinger’s filesystem, PHP throws a write error every time.
Here’s how to check and clear it:
- In hPanel, go to Databases → phpMyAdmin and log into your site’s database.
- Open the
wp_optionstable (your table prefix might be different, likewp_abc123_options). - Head to the SQL tab and run this query:
SELECT option_name, option_value FROM wp_options WHERE option_name = 'upload_path';If the option_value contains an old path like /var/www/vhosts/... or /home/olduser/..., edit the row and clear it out completely. When upload_path is empty, WordPress falls back to the default relative path: wp-content/uploads.
What I Ran: Real Diagnostics via WP-CLI
Whenever I hit this error, I skip the browser UI and test the upload pipeline directly through the command line. This helps isolate whether the issue is PHP-wide or tied to another server headache like a WordPress 504 Gateway Timeout on Hostinger or a database connection failure.
SSH into your site and use the WP-CLI media import command to test an upload from the terminal:
# Download a test asset and pipe it directly to WP-CLI
wget https://raw.githubusercontent.com/wp-cli/wp-cli/main/templates/screenshot.png -O /tmp/test-upload.png
# Import the image into WordPress
wp media import /tmp/test-upload.png --title="Test Upload"If that returns Success: Imported file /tmp/test-upload.png as media ID ..., your PHP upload handling and filesystem permissions are working. You can clean up the test image by running rm /tmp/test-upload.png.
Frequently Asked Questions
Why does setting folder permissions to 777 cause more upload errors?
Hostinger runs PHP processes via PHP-FPM under suEXEC environments. When a directory is set to 777 (world-writable), the server’s security filters proactively block write access to stop rogue scripts from executing. Stick to 755 for directories.
Why does this error occur only with specific image formats or ZIP files?
If small images upload fine but ZIP files or large high-res photos throw this error, you’re hitting your upload_max_filesize or post_max_size limits. When PHP truncates an oversized upload stream mid-flight, it often registers as a write failure instead of a clear size warning.
Where are the PHP error logs located in Hostinger hPanel?
In hPanel, head to Advanced → PHP Configuration → PHP Extensions to verify error logging is enabled. You can view live runtime errors under Logs → Access Logs / Error Logs.
Next Steps
Once your media library is writing files again, make sure your PHP environment has enough headroom to handle larger themes and plugin updates. Check out our walkthrough on how to increase WordPress PHP memory limit and max upload size in Hostinger so you don’t run into upload bottlenecks down the road.

