# Fix WordPress Upload Failed Error

You try to upload an image, PDF, or video to WordPress and get an error. Maybe it says "HTTP error," "Sorry, this file type is not permitted," or just "Upload failed." The Media Library is central to WordPress, and upload failures stop content creation cold.

Upload failures have multiple causes: file permissions, size limits, server configuration, file type restrictions, and more. Let's diagnose and fix each one.

Quick Diagnosis

```bash # Check upload directory permissions ls -la wp-content/uploads/

# Check current upload limits wp eval 'echo "Max upload: " . size_format(wp_max_upload_size()) . "\n";' wp eval 'echo "Post max: " . ini_get("post_max_size") . "\n";' wp eval 'echo "Upload max: " . ini_get("upload_max_filesize") . "\n";'

# Check allowed MIME types wp eval 'print_r(get_allowed_mime_types());'

# Check disk space df -h . ```

HTTP Error on Upload

The generic "HTTP error" message is frustrating. It usually means PHP hit a limit.

Increase PHP Limits

Add to wp-config.php:

php
// Increase upload limits
define('WP_MEMORY_LIMIT', '256M');

Create or edit php.ini in WordPress root:

ini
upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 300
max_input_time = 300
memory_limit = 256M

Or add to .htaccess (Apache):

apache
php_value upload_max_filesize 64M
php_value post_max_size 64M
php_value max_execution_time 300
php_value max_input_time 300

Increase Nginx Limits

For Nginx servers, edit nginx.conf:

nginx
client_max_body_size 64M;

Reload Nginx:

bash
sudo nginx -t && sudo nginx -s reload

Check Server Error Logs

```bash # Apache error log tail -50 /var/log/apache2/error.log

# Nginx error log tail -50 /var/log/nginx/error.log

# PHP-FPM log tail -50 /var/log/php8.1-fpm/error.log

# WordPress debug log tail -50 wp-content/debug.log ```

Disable ModSecurity Temporarily

ModSecurity can block uploads:

```bash # Check if ModSecurity is enabled apache2ctl -M | grep security

# Disable for testing sudo a2dismod security2 sudo systemctl restart apache2 ```

If uploads work without ModSecurity, add an exception rather than leaving it disabled.

Permission Denied Errors

"Unable to create directory" or "Permission denied" means the server can't write to uploads.

Fix Upload Directory Permissions

```bash # Set correct ownership chown -R www-data:www-data wp-content/uploads/

# Set correct permissions find wp-content/uploads/ -type d -exec chmod 755 {} \; find wp-content/uploads/ -type f -exec chmod 644 {} \;

# Make sure wp-content is writable chmod 755 wp-content/ ```

Check if Uploads Directory Exists

bash
# Create uploads directory if missing
mkdir -p wp-content/uploads/$(date +%Y)/$(date +%m)
chmod -R 755 wp-content/uploads/
chown -R www-data:www-data wp-content/uploads/

Verify Server User

```bash # What user is PHP running as? wp eval 'echo "User: " . get_current_user() . "\n";' ps aux | grep php

# Make uploads owned by that user chown -R www-data:www-data wp-content/uploads/ ```

File Type Not Permitted

"Sorry, this file type is not permitted for security reasons."

Add Allowed File Types

php
// In theme's functions.php or custom plugin
add_filter('upload_mimes', function($mimes) {
    $mimes['svg'] = 'image/svg+xml';
    $mimes['webp'] = 'image/webp';
    $mimes['pdf'] = 'application/pdf';
    $mimes['doc'] = 'application/msword';
    $mimes['docx'] = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
    return $mimes;
});

Allow All File Types (Not Recommended)

php
// In wp-config.php - use with caution
define('ALLOW_UNFILTERED_UPLOADS', true);

This disables MIME type checking. Only use temporarily for debugging.

Check Current Allowed Types

bash
wp eval 'print_r(get_allowed_mime_types());'

File Size Exceeded

"The uploaded file exceeds the upload_max_filesize directive in php.ini."

Find Your php.ini

bash
# Find loaded php.ini
php -i | grep "Loaded Configuration File"
wp eval 'echo php_ini_loaded_file() . "\n";'

Edit php.ini

ini
upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 300

Restart PHP-FPM:

bash
sudo systemctl restart php8.1-fpm

Verify Changes

bash
wp eval 'echo ini_get("upload_max_filesize") . "\n";'
wp eval 'echo ini_get("post_max_size") . "\n";'

Image Upload Issues

Image Processing Errors

If image uploads fail with processing errors, ImageMagick or GD might be missing:

```bash # Check PHP extensions php -m | grep -i "gd|imagick|exif"

# Install missing extensions sudo apt install php8.1-gd php8.1-imagick php8.1-exif sudo systemctl restart php8.1-fpm ```

Switch Image Editor

WordPress tries Imagick first, then GD. Force GD if Imagick causes issues:

php
// In functions.php
add_filter('wp_image_editors', function() {
    return array('WP_Image_Editor_GD', 'WP_Image_Editor_Imagick');
});

Image Memory Issues

Large images need more memory:

php
// In wp-config.php
define('WP_MEMORY_LIMIT', '512M');

Missing Temporary Folder

"Missing a temporary folder."

Check PHP Temp Directory

bash
wp eval 'echo sys_get_temp_dir() . "\n";'
wp eval 'echo ini_get("upload_tmp_dir") . "\n";'

Set Temp Directory

Create and configure a temp directory:

bash
mkdir -p wp-content/tmp
chmod 755 wp-content/tmp
chown www-data:www-data wp-content/tmp

Add to wp-config.php:

php
define('WP_TEMP_DIR', ABSPATH . 'wp-content/tmp');

Security Plugin Blocking

Security plugins may block uploads.

Temporarily Disable Security Plugins

bash
wp plugin deactivate wordfence
wp plugin deactivate iThemes-security
wp plugin deactivate sucuri-scanner

Test upload. If it works, check the security plugin's settings for upload restrictions.

Check .htaccess for Blocks

bash
grep -i "deny\|block\|forbidden" .htaccess

Upload via WP-CLI Alternative

If browser upload fails, use WP-CLI:

```bash # Import from local file wp media import /path/to/image.jpg

# Import from URL wp media import https://example.com/image.jpg

# Import and attach to post wp media import image.jpg --post_id=123 --title="My Image"

# Create thumbnails wp media regenerate ```

Debug Upload Process

Enable Debug Mode

php
// In wp-config.php
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);

Check Upload Errors

bash
tail -f wp-content/debug.log | grep -i upload

Use Debug Plugin

bash
wp plugin install query-monitor --activate

Query Monitor shows PHP errors and warnings during upload.

Nginx-Specific Issues

Client Max Body Size

nginx
# In http, server, or location block
client_max_body_size 64M;

FastCGI Buffers

For large uploads:

nginx
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
fastcgi_read_timeout 300;

Apache-Specific Issues

LimitRequestBody

apache
# In .htaccess or Apache config
LimitRequestBody 67108864

Timeouts

apache
Timeout 300
ProxyTimeout 300

Multisite Upload Issues

For WordPress Multisite, network settings also limit uploads.

Check Network Settings

```bash # Get site upload limits wp site meta get 1 upload_limit wp site meta get 1 upload_filetypes

# Or via network admin # Settings > Network Settings > Upload Settings ```

Update Network Limits

bash
wp site meta update 1 upload_limit 64
wp site meta update 1 upload_filetypes "jpg jpeg png gif mp4 pdf"

Verification Checklist

After fixing:

```bash # Test upload via WP-CLI wp media import test-image.jpg --title="Test Upload"

# Check media library wp media list --per_page=5

# Verify file permissions ls -la wp-content/uploads/

# Check limits wp eval 'echo "Max upload: " . size_format(wp_max_upload_size()) . "\n";' ```

Quick Reference

ErrorCauseFix
HTTP errorPHP limitIncrease memory, execution time
Permission deniedFile permissionschown/chmod uploads directory
File type not permittedMIME type restrictionAdd to upload_mimes filter
File size exceededphp.ini limitIncrease upload_max_filesize
Missing temp folderNo temp directorySet WP_TEMP_DIR
HTTP 413Server limitIncrease client_max_body_size (Nginx)

Upload issues are usually straightforward: check permissions, increase limits, and verify file types. Start with WP-CLI upload to bypass browser issues, then fix the server configuration.