WORDPRESS
July 30, 2026

How to Fix WordPress Image Upload "HTTP Error"

7 min read
Author
CloudStick Team
Security Specialist
Share this article
How to Fix WordPress Image Upload "HTTP Error"
CloudStick
Upload
HTTP Error

Why "HTTP Error" Tells You Nothing

The generic "HTTP error" you see in the Media Library is WordPress giving up and reporting nothing useful, because the actual failure happened one layer down, inside the image-processing call it made to generate thumbnail sizes. WordPress does not just store the file you uploaded; the moment it lands, core hands the image off to whichever PHP image library is available, GD or Imagick, and asks it to generate every registered thumbnail size, thumbnail, medium, large, and whatever your theme or plugins have added on top. If that call throws a fatal error, runs out of memory, or the request simply times out mid-processing, WordPress catches the failure at the AJAX layer and surfaces the same flat "HTTP error" regardless of what actually went wrong underneath.

That is why guessing rarely works and why so many people end up reinstalling themes or deactivating random plugins with no result. In practice, four causes account for nearly every instance of this error: PHP's memory_limit gets exhausted while GD or Imagick is generating one of the thumbnail sizes, because a large image needs far more memory to process than its file size on disk suggests; the GD or Imagick PHP extension is missing, disabled, or broken on the server; upload_max_filesize or post_max_size is set too low so the file never fully arrives at PHP in the first place; or max_execution_time is too short for a large image or a big batch upload. Everything below works through those four causes in the order that actually isolates the problem fastest.

Check Whether GD or Imagick Is Actually Active

Before touching any memory or timeout setting, confirm the image library WordPress needs is actually installed and enabled for the PHP version the site is running, because a missing extension produces the exact same "HTTP error" as a memory exhaustion and wastes time if you fix the wrong thing first. WordPress prefers Imagick when it is available and falls back to GD, so both need to be checked.

php -m | grep -i 'gd\|imagick'
# expect to see "gd" and/or "imagick" printed back
wp media regenerate --yes
# run wp-cli from the site root to force-regenerate thumbnails
# and surface the real PHP error instead of the AJAX one

If php -m returns nothing for either library, the extension is not installed for that PHP version, and no amount of memory or timeout tuning will fix an upload on its own. You can also confirm the same thing by checking phpinfo() output for a site through a small script, or looking under the GD and Imagick sections directly, both should appear as enabled with their configuration details listed if the extension is genuinely active. Running wp media regenerate is the more useful check in practice, because instead of the vague AJAX message, wp-cli surfaces the actual PHP warning or fatal error, which usually names the exact cause, an allowed memory size exhausted message, an Imagick exception, or a specific file that fails while others succeed. On a CloudStick server, EasyPHP lets you install or verify the GD or Imagick extension and adjust the upload and memory limits per site directly from the dashboard, so you do not have to hunt down which php.ini belongs to which PHP-FPM pool by hand.

Raise memory_limit and max_execution_time in PHP-FPM

If the extension is confirmed present, memory exhaustion during thumbnail generation is the next most likely cause, and it catches people off guard because the numbers involved are much larger than the file size on disk implies. GD needs roughly width multiplied by height multiplied by four bytes of memory just to hold one uncompressed copy of the image in memory while it works, before it has even generated a single thumbnail size. A 6000x4000 pixel photo straight off a modern phone or camera, only a few megabytes as a JPEG on disk, decompresses to around 96MB in raw memory, and WordPress needs enough headroom left over to hold that plus every additional thumbnail size it is about to generate from it. A default memory_limit of 128M or even 256M can fail on exactly this kind of image while smaller uploads succeed without issue.

The fix belongs in the PHP-FPM pool configuration for the site, not just wp-config.php, since a WordPress-level define can be overridden or ignored depending on how the hosting stack is set up, while the pool-level value is authoritative for that PHP-FPM worker.

; /etc/php83cs/fpm-pools.d/example.com.conf
php_admin_value[memory_limit] = 512M
php_admin_value[max_execution_time] = 300
systemctl reload php83cs-fpm

Raising max_execution_time alongside memory_limit matters for the same reason: generating several thumbnail sizes from one large image, or processing a batch of images uploaded together, can genuinely take longer than the default 30 seconds, and a request that gets killed mid-process by the timeout produces the same unhelpful "HTTP error" as running out of memory. Reload the PHP-FPM service after editing the pool file so the new limits actually apply to the worker handling that site's requests.

Fix upload_max_filesize and post_max_size Together

If the file itself never fully reaches PHP, no amount of memory or timeout tuning helps, because there is nothing yet for GD or Imagick to process. This happens when upload_max_filesize is lower than the actual file size, but it also happens in a subtler way when post_max_size is left at its default while upload_max_filesize was raised on its own, since post_max_size caps the entire POST request body, including the file plus all its form data, and it must be greater than or equal to upload_max_filesize or the upload silently fails before PHP even sees it as an upload.

PREREQUISITE

Always raise upload_max_filesize and post_max_size together, never one alone. post_max_size must be set equal to or higher than upload_max_filesize, since it governs the whole request body the file rides inside. Setting only upload_max_filesize higher while post_max_size stays at its old, lower default just moves the failure point without actually fixing it.

; /etc/php83cs/fpm-pools.d/example.com.conf
php_admin_value[upload_max_filesize] = 128M
php_admin_value[post_max_size] = 132M
systemctl reload php83cs-fpm

Give post_max_size a small margin above upload_max_filesize rather than setting them identical, since the request also carries the form fields WordPress sends alongside the file itself, nonce, action, attachment metadata, and a value set exactly equal can still clip on the largest uploads. Reload the PHP-FPM pool after any change here for the same reason as the memory settings, the running worker needs to pick up the new configuration before it takes effect on the next request.

Test With a Smaller Image to Isolate the Real Cause

The fastest way to tell a size or memory problem apart from a broken extension is to upload a small, simple image, something under 500KB and modest in pixel dimensions, right after making your changes. If the small image uploads and generates thumbnails without issue but the original large file still fails, the cause was size or memory-related and you should keep raising memory_limit and re-testing with progressively larger files until you find the ceiling the site actually needs. If even the tiny test image fails with the same "HTTP error," the problem was never about size at all, go back and re-check that GD or Imagick is genuinely enabled and correctly configured for the exact PHP version the site is running, since a mismatch between the PHP-FPM pool version and the extension you installed is an easy thing to overlook.

As a quick recap: confirm GD or Imagick is active with php -m or by running wp media regenerate to surface the real error, raise memory_limit and max_execution_time in the site's PHP-FPM pool rather than only in wp-config.php, raise upload_max_filesize and post_max_size together with post_max_size set slightly higher, and use a small test image to prove whether you are chasing a size ceiling or a broken extension. Once uploads succeed reliably, it is worth checking your other sites on the same server too, since default PHP limits are usually set once per pool and every WordPress install sharing that configuration is exposed to the same failure the moment someone uploads a large photo.

Leave a comment
Full Name
Email Address
Message
Contents