2026年11月12日
2026年11月12日
WordPress Media Upload Fails or Times Out: PHP, Nginx, Apache Limits
This article is a localized edition of the Japanese original. Read the Japanese original
WordPress media uploads fail for three main reasons: size limits, time limits, and the load of image processing. Each layer has its own limits, including PHP, the web server (Nginx or Apache) and any CDN, and the upload fails if any one of them is too small. This article shows how to identify the layer from the symptom and how to change each setting. PHP versions and paths use Ubuntu 24.04 (PHP 8.3) as of October 2026 as the example.
Identify the cause from the symptom
| Symptom | Likely cause |
|---|---|
| Before uploading, a message says the file exceeds the maximum upload size for this site | PHP upload_max_filesize or post_max_size |
413 Request Entity Too Large |
Nginx client_max_body_size, Apache LimitRequestBody, or a CDN limit |
Progress runs for a while, then 504 Gateway Timeout or the upload stalls |
Nginx fastcgi_read_timeout, Apache Timeout/ProxyTimeout, PHP-FPM request_terminate_timeout |
| Only large images fail with "HTTP error" or a message saying the server cannot process the image | Out of memory or time while resizing images and creating thumbnails |
In the Network tab of your browser's developer tools, look at the status code of the request to async-upload.php (uploads from the Media Library) or /wp-json/wp/v2/media (uploads from the block editor) to see which layer stops it. Check the web server's error log as well (/var/log/nginx/error.log for Nginx).
Check the current limits
The maximum size WordPress accepts is shown as "Maximum upload file size" on the Media → Add New screen. You can check PHP values such as upload_max_filesize, post_max_size, the PHP time limit and the memory limit in the Server section of the Info tab under Tools → Site Health.
If you have WP-CLI, you can also check with this command:
wp eval 'echo size_format( wp_max_upload_size() ), PHP_EOL;'
However, WP-CLI runs with the CLI PHP settings, so it shows the CLI values, which can differ from the web side (PHP-FPM and so on). Check the values used for web requests in the admin screen or Site Health.
Raise the PHP limits
Settings to change
| Setting | Meaning | Example |
|---|---|---|
upload_max_filesize |
Maximum size of one file | 256M |
post_max_size |
Maximum size of a whole submission (POST). Make it larger than upload_max_filesize |
264M |
memory_limit |
Memory available to one request. The PHP manual says it should generally be larger than post_max_size |
512M |
max_execution_time |
Maximum script execution time (seconds) | 300 |
max_input_time |
Maximum time to receive and parse input data (seconds) | 300 |
max_execution_time is the time the PHP script spends executing, not the time spent transferring the file. It matters when resizing images and creating thumbnails after the upload takes a long time. Raise it only as far as you need and do not make it excessively large.
With PHP-FPM (Nginx, or modern Apache setups)
With PHP-FPM, php_value in .htaccess does not work (php_value is syntax for mod_php built into Apache; in a PHP-FPM setup it is either ignored or causes a 500 error). Add a configuration file for PHP-FPM instead.
# Check which PHP version is in use
ls /etc/php/
# Create an extra config file for FPM (8.3 is an example; use the version you found)
sudo nano /etc/php/8.3/fpm/conf.d/99-upload.ini
upload_max_filesize = 256M
post_max_size = 264M
memory_limit = 512M
max_execution_time = 300
max_input_time = 300
sudo systemctl restart php8.3-fpm
On RHEL-based systems (AlmaLinux, Rocky Linux, etc.), put the extra config file in /etc/php.d/ and restart with sudo systemctl restart php-fpm.
If you set request_terminate_timeout in the PHP-FPM pool configuration (/etc/php/8.3/fpm/pool.d/www.conf on Debian/Ubuntu), requests that exceed that many seconds are killed. The default is 0 (disabled). If you set it, make it at least as large as max_execution_time.
If you cannot edit the server configuration files, you can place a .user.ini in the WordPress directory. The syntax is the same as the ini above. .user.ini is re-read every five minutes by default, so changes can take a while to apply.
With mod_php (PHP built into Apache)
Only when PHP runs as Apache's mod_php can you write the following in .htaccess (it must be allowed by AllowOverride).
php_value upload_max_filesize 256M
php_value post_max_size 264M
php_value max_execution_time 300
php_value max_input_time 300
If you are not sure which one you use, check PHP SAPI in Site Health under Info → Server (fpm-fcgi means PHP-FPM, apache2handler means mod_php).
On shared hosting
Many shared hosting providers have an item in their control panel for changing PHP settings (php.ini settings). Change upload_max_filesize and the others there. Users often cannot change web server limits or timeouts, so if uploads still fail, check the limits in your hosting provider's documentation.
Raise the web server limits
Nginx
Nginx returns 413 when the request body exceeds client_max_body_size (default 1m). The time it waits for a response from PHP-FPM is fastcgi_read_timeout (default 60 seconds); beyond that it returns 504.
server {
# ...
client_max_body_size 264M;
location ~ \.php$ {
# ...
fastcgi_read_timeout 300s;
}
}
sudo nginx -t && sudo systemctl reload nginx
Apache
Apache's LimitRequestBody defaults to 1 GiB (1073741824 bytes) since 2.4.54 (unlimited in 2.4.53 and earlier). At the default it is usually not a problem, but check the value if your configuration lowers it. The wait time is Timeout (default 60 seconds), and if you pass requests to PHP-FPM through mod_proxy_fcgi, ProxyTimeout (the Timeout value if unset) also applies. Timeout and ProxyTimeout cannot go in .htaccess; put them in the server-wide or VirtualHost configuration.
Timeout 300
ProxyTimeout 300
LimitRequestBody 276824064
sudo apachectl configtest && sudo systemctl reload apache2
Check CDN and WAF limits
If traffic goes through a CDN such as Cloudflare, the CDN also limits upload size. For example, as of October 2026 Cloudflare's request body limit on the Free and Pro plans is 100MB. Files larger than that cannot be uploaded no matter how you configure the server. A WAF (web application firewall) may also block uploads, so check the WAF logs too.
When image processing fails
WordPress creates several sizes, such as thumbnails, from each uploaded image. Since 5.3 it also creates and uses a scaled-down copy (with -scaled in the file name) of images whose width or height exceeds 2560 pixels. With high-resolution photos, this processing can run out of memory or time and fail with "HTTP error" or similar.
What to do:
- Resize and compress images before uploading. For display on the web, 2560 pixels or less is usually enough
- Raise the memory limit used for image processing in the admin. During image processing WordPress raises the memory limit up to
WP_MAX_MEMORY_LIMIT(default 256M). If PHP'smemory_limitis larger, that value is used instead
// wp-config.php (above the "That's all, stop editing!" line)
define( 'WP_MAX_MEMORY_LIMIT', '512M' );
- Check that the image library (Imagick or GD) is available in the media section of the Info tab in Site Health
Place large videos on the server and register them
For videos of several hundred MB or more, instead of insisting on a browser upload, you can transfer the file to the server over SFTP and register it in the Media Library with WP-CLI.
wp media import /home/deploy/upload/movie.mp4 --title="Company introduction video"
This bypasses the PHP and web server upload limits. Because of bandwidth and storage for playback, though, large videos are sometimes better hosted on a video service and embedded.
Check after the change
- Does "Maximum upload file size" on Media → Add New show the new value?
- Upload the file that failed again and check that thumbnails are created
- In the Info tab of Site Health, are the PHP limits at the values you set?
Summary
- Upload failures come in three kinds: size, time and image processing. Tell the layer apart by symptoms such as 413, 504 and HTTP error
- Set PHP in the order
upload_max_filesize<post_max_size<memory_limit. With PHP-FPM,php_valuein.htaccesshas no effect, so use an FPM ini file or.user.ini - For Nginx check
client_max_body_sizeandfastcgi_read_timeout; for Apache checkLimitRequestBody,TimeoutandProxyTimeout - Files above a CDN limit (100MB on Cloudflare Free and Pro) cannot be fixed with server settings
- Resize large images beforehand, and register large videos with SFTP and
wp media import
Related articles:
- Adjusting Nginx client_max_body_size to allow file uploads
- Tuning Nginx timeouts (causes of 504 and 408 and matching PHP-FPM)
- Tuning Apache timeout settings
- Installing PHP and basic settings (php.ini location and what to review first)
Questions about WordPress? The publisher of this site is based in Japan and replies in Japanese. Contact (Japanese)