[wp-trac] [WordPress Trac] #50250: In WordPress 5x, Image uploads frequently fail, and do so with a spurious error message
WordPress Trac
noreply at wordpress.org
Fri Jun 12 02:25:30 UTC 2020
#50250: In WordPress 5x, Image uploads frequently fail, and do so with a spurious
error message
-----------------------------+------------------------------
Reporter: toomanyairmiles | Owner: (none)
Type: defect (bug) | Status: new
Priority: normal | Milestone: Awaiting Review
Component: Media | Version: 5.4.2
Severity: major | Resolution:
Keywords: | Focuses:
-----------------------------+------------------------------
Changes (by codemilitant):
* version: => 5.4.2
Comment:
@azaozz I can say that this is not the fault of WordPress, but the fault
of default server configurations. My discipline as a server DevOps focuses
on Nginx, and when I ran into this problem, my KVM frontend (Nginx KVM)
crashed before routing to all my upstream servers. The low default
configurations in Nginx, and the default SELinux, were the problem. It's
not necessary to crank up the Nginx memory limits to 10M or more, as I've
seen posted elsewhere, instead, just disable the `client_max_body_size`,
then update the `client_body_buffer_size` to a modern configuration for
WordPress.
Server: `CentOS 7`
Kernel: `Linux version 3.10.0-1127.8.2.el7.x86_64`
Like this:
client_body_buffer_size 1m;
client_max_body_size 0;
Context: http, server, location
As noted here on nginx.org:
Default: client_body_buffer_size 8k|16k;
Default: client_max_body_size 1m;
Context: http, server, location
Setting (client_max_body) size to 0 disables checking of client
request body size.
It gets the client request body from:
the maximum allowed size of the client request body, specified in the
“Content-Length” request header field.
These server defaults are problematic, and will most likely fail WordPress
for most default Nginx configs running this latest version of WordPress
since most "Content-Length" for a large file will be considerably more
than 1MB. Since images (any media) report a "Content-Length" in the
header, this will easily surpass default Nginx configurations, and throw
the request into the `client_body_temp_path`.
In my tests, it doesn't look like WordPress combines multiple image
uploads into a single "Content-Length" header, but if I'm mistaken, then
this should be corrected to submit each media element in it's own request
to ensure "Content-Length" is not unnecessarily overloading the server by
combining all media sizes into a single request header.
The second element is SELinux. While most web hosts, depending on the
service selected, do not enable SELinux, in my case, I have website
clients that routinely pump out over 2 million page views, so I have
SELinux enabled (Enforcing) for their safety.
Unfortunately, the default configuration for SELinux does not contain any
default policies within the `file_contexts` for Nginx caching. Whether or
not `fastcgi_cache, proxy_cache, etc...` are enabled, the
`client_body_temp_path`, will be used for memory overruns. By default
this is stored in `/var/cache/nginx`. SELinux does not have a default
policy for `/var/cache/nginx`, so this will result in:
2020/06/11 16:22:29 [crit] 17420#17420: *8041 open()
"/var/cache/nginx/client_temp/0000000362" failed (13: Permission denied),
client: 192.168.101.100, server: example.com, request: "POST /wp-admin
/async-upload.php HTTP/2.0", host: "example.com", referrer:
"https://example.com/wp-admin/media-new.php"
Of course, this will kill the upload and throw either of:
- Unexpected response from the server. The file may have been uploaded
successfully. Check in the Media Library or reload the page.
- Post-processing of the image failed likely because the server is
busy or does not have enough resources. Uploading a smaller image may
help. Suggested maximum size is 2500 pixels.
To fix the default SELinux, do the following as root:
# Configure Nginx cache for new WordPress media upload
semanage fcontext -a -t httpd_cache_t
"/var/cache/nginx/client_temp(/.*)?"
restorecon -R -v /var/cache/nginx/client_temp
Since most webhosts disable SELinux for shared hosting, this is not an
issue, and you shouldn't encouter many issues. However, any VPS or
dedicated server could easily run into issues, and throw multiple errors.
Once the new SELinux configs are enabled, the successful response will
look like:
2020/06/11 16:48:00 [warn] 17420#17420: *9283 a client request body is
buffered to a temporary file /var/cache/nginx/client_temp/0000000485,
client: 192.168.101.100, server: example.com, request: "POST /wp-admin
/async-upload.php HTTP/2.0", host: "example.com", referrer:
"https://example.com/wp-admin/media-new.php"
If it's not possible to update the SELinux policy, another solution would
be to direct the Nginx `client_body_temp_path` to a folder that already
has a proper SELinux policy for processing web server requests.
Something like:
client_body_temp_path /var/www/html/yourdomain/wp-content/client_temp
1 2;
Context: http, server, location
This doesn't have to be the `/var/www/` directory, but could be
`/home/user/public_html/wp-content/client_temp` for just about any shared
hosting.
Thank you for all the hard work on this new Media Library.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/50250#comment:3>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list