Since WordPress 7.1 the same image upload takes one of two roads
From 19 August an image dropped into the block editor from Chrome is resized in the browser, and three server hooks never run. The same file uploaded from Firefox, through the media library, on a WooCommerce product page or by an n8n workflow goes the old way. Nothing tells you which road a given image took, and WordPress says plugins that act on thumbnails "should keep working" and, in the next breath, "should be checked".
Three hooks that never fire
WordPress 7.1 shipped on 19 August 2026 with a change to how images are uploaded. The developer note, published four weeks earlier, opens with it:
WordPress 7.1 ships client-side media processing – a capability that handles image compression, resizing, format conversion, rotation, and thumbnail generation directly in the user's browser using WebAssembly, rather than on the server. The feature is enabled by default in supporting browsers.
- Client-Side Media Processing in WordPress 7.1, Make WordPress Core, 22 July 2026, read 12 September 2026
For a site owner the practical sentence is further down, under a heading that says exactly what it means:
Server specific hooks don't fire
Because a server side editor is not used,
wp_image_editors,image_memory_limitandimage_make_intermediate_sizenever fire.
- same note
Those are the hooks a plugin uses to substitute its own image engine, to raise the memory limit for large files, and to do something to each thumbnail as the server writes it - a watermark, a conversion, a copy to a CDN. The developer handbook adds that this is deliberate: the three "are intentionally left silent: firing them artificially would mislead plugins into thinking they can alter files that were already encoded in the browser."
That last clause is the whole mechanism. The thumbnails are made from the original file in the browser, before the server has seen anything, and then uploaded one by one. Whatever the server used to do to them at creation time, it no longer has the chance to do.
Which uploads take the new road
Not all of them, and the conditions are narrower than "WordPress 7.1". Reading the 7.1.0 source and the note together, an upload is processed in the browser only when all of the following hold:
- The site is on HTTPS. The feature gate in
media.phpsets the default to enabled only whenis_ssl()is true or the host islocalhost- the code comment says "This is due to SharedArrayBuffer requiring a secure context". A site still served over plain HTTP is on the old path without anyone having chosen it. - The browser is Chrome or Edge 137 or newer on desktop, or Chrome 146 or newer on Android - or any other Chromium browser reporting that version. The note's table lists Firefox and Safari as "Not supported (no Document-Isolation-Policy) – falls back to server-side". The server sends the isolation header only when the user agent reports a Chromium major version of 137 or above.
- The upload happens on a block editor screen - the post or page editor, the site editor, the block widgets screen. The function that sets up the isolation header returns early if the current screen is not a block editor. The media library, the classic editor, and the old-style upload dialog are not on the list, and the note's author says so directly when telling a plugin developer how to test both paths: "using Chrome/Firefox or doing uploads in the editor vs the media library".
- The machine and connection pass a set of checks - more than 2 GB of
device memory, at least two cores, not a 2G connection, no Save-Data header, a
content security policy that allows
blob:workers. Failing any of them "causes a transparent fallback to server-side processing – there is no user-facing change".
Everything else goes the way it went in 7.0. Two cases matter for shops in particular.
WooCommerce product images are not affected. WooCommerce turns the block
editor off for the product post type - a two-line filter in its post-types
class returns false for product and leaves everything else alone - so the
product edit screen is a classic screen, its featured image and gallery go
through the classic uploader, and the isolation header is never sent there. The
same shop's blog posts and pages, edited in the block editor, are on the new
path. So the question "did this image go through the browser" has a different
answer for a product photo and for the hero image on the About page, uploaded by
the same person in the same session.
Uploads from automations are not affected. An n8n or Make workflow that
posts a file to /wp/v2/media gets server-side thumbnails, because the REST
parameter that turns them off - generate_sub_sizes - defaults to true in the
7.1.0 controller and it is the browser pipeline that sends it as false. Without it,
the request runs through wp_generate_attachment_metadata() and on into the GD
or Imagick editor, where image_make_intermediate_size fires as before.
Between those two lists, the diagnostic question for any image that came out wrong since August is one no support form asks: which browser, and from which screen.
"Should keep working", "should be checked"
The note addresses plugin authors twice, in different sections of the same document:
Plugins for watermarking, CDN sync, custom metadata processing, and similar use cases continue to work without modification – write them idempotently so they handle both passes correctly.
- same note, "Server-side hooks still fire"
Watermarking, CDN sync, custom metadata processing, and similar plugins should keep working without modification, but should be checked to make sure they handle both passes.
- same note, FAQ
"Both passes" is the part that decides it. On the old path, the filter that
plugins hang their work on - wp_generate_attachment_metadata - normally fires
once, with the full list of thumbnails already written to disk. On the new path it fires
twice: once when the original arrives, with an empty list of sizes, and again
after the browser has uploaded every thumbnail and called a new "finalize"
endpoint, this time with the full list. A plugin that does its work when the
filter fires, and does it once, does it on the first pass, on an original with no
thumbnails yet.
What the check finds
We read the two most-installed free plugins in the WordPress.org directory whose purpose is watermarking against this. Neither has been tested by its author on 7.1: Image Watermark's directory page said "Tested up to 7.0.4" on 12 September, and Easy Watermark's said 6.8.8, its last update being August 2025.
Image Watermark registers its watermarking callback from inside the handler
for wp_handle_upload - that is, only during a request that contains an uploaded
file. On the new path, the request that carries the original does, so the
callback is registered for the first pass, where the size list is empty and the
plugin's own loop skips every size it cannot find. The thumbnails arrive in
separate requests where the upload handler runs but the metadata filter is never
applied, and the finalize request - the second pass, the one with the full list -
contains no file, so the handler never runs and the callback is never registered.
Reading the code, the thumbnails are written to disk exactly as the browser made
them.
Easy Watermark hooks the filter directly, so it sees both passes, and keeps a per-attachment list of watermarks it has already applied. If the watermark is configured to cover the full-size image as well as thumbnails, the first pass applies it to the full-size file, records it as applied, and the second pass filters it out as done - and the thumbnails are skipped. If the watermark is configured for thumbnail sizes only, the first pass does nothing, nothing is recorded, and the second pass applies it normally. Whether it breaks depends on one checkbox in its settings.
We have not run either plugin on 7.1; this is what the code says will happen.
The test takes five minutes on any 7.1 site over HTTPS: upload the same JPEG
twice from Chrome, once into a post in the block editor and once through Media →
Add Media File, then open both attachments and compare the -1024x… files. If the
watermark is on one and not the other, this is why.
What the result looks like on the page is worth spelling out, because it is not
"no watermark". When the full size is among the watermarked sizes, the full-size
file is watermarked. The copy the block actually
displays - typically the large size - is the browser's, and is clean. A
right-click and "open image in new tab" from the front end shows the clean one.
The optimizers moved first
The premise that optimization plugins would silently skip files does not hold on 12 September, and the reason is that the vendors got there before the release. Imagify's changelog for version 2.3.3, tagged at 13:41 UTC on 19 August, ten hours before WordPress 7.1 itself:
Fix: Thumbnails from WordPress 7.1 client-side uploads are now optimized instead of skipped.
- Imagify changelog, version 2.3.3, read 12 September 2026
Which is also the only vendor statement we found that confirms the skip existed: on 2.3.2 and earlier, with the 7.1 betas, the browser's thumbnails were not optimized. EWWW Image Optimizer 8.7.6, dated 20 August, lists "fixed: compatibility with client-side media processing in WP 7.1" and, more tellingly, "added: option to disable client-side media processing in WP 7.1, mostly for animated GIF images and indexed (palette) PNG images" - WordPress itself ships no such switch outside a code filter. WP Offload Media 3.4.0 followed on 3 September with "WordPress 7.1 compatible" and three fixes for 7.1 behaviour.
Searching the source of every plugin in the directory for a registration on
image_make_intermediate_size, the hook that never fires, returns 21 plugins.
The largest - Smush, WebP Converter for Media, WebP Express - all also hook
something that does fire on the new path, and from their code none of them loses
its main function to this change. The plugins that do lose something are the
ones whose only handle on the thumbnails was that hook, and the ones that assumed
a single pass. The signal to look for is the "Tested up to" line on the plugin's
page, and a changelog with nothing about 7.1 in it.
Smush's author, answering a user who asked whether the plugin was still needed, added: "the client side thumbnails are bigger than their PHP side counterparts in many situations". The browser's encoder is not the server's. A regression of the same kind, indexed PNGs coming out larger than the original, was filed by EWWW's author the day after release and was scheduled for 7.1.1.
What is not quiet about it
Not everything about this feature is quiet. Two effects were visible on 12 September and are worth checking against whatever version you are on now.
Media on a CDN can stop playing in the editor. In 7.1.0, when the isolation
header is active, the server and a script in the editor add
crossorigin="anonymous" to cross-origin video, audio, script and link tags.
That turns each load into a CORS request, "which fails for any host that does
not send Access-Control-Allow-Origin - media offloaded to a CDN being the
common case", in the bug report the feature's lead filed on 9 September. A video block whose file lives on such a host fails in the editor
with media error code 4. The front end is unaffected. The core fix was an open
pull request on 12 September and was not in the 7.1.1 release candidate
published two days earlier.
GIFs are not turned into videos on their own. The note's description of GIF
handling has been read as "animated GIFs become <video>", and that is not what
ships. The attachment "stays a single image/gif attachment in the media
library"; the browser produces a companion MP4 or WebM, and the editor offers a
"Display as video" control on a standalone Image block that the user may click
or not. Inside a gallery the control is not offered. On a product page nothing
happens at all, for the reason above.
How to tell what a given image went through
- Check the two preconditions. Is the site on HTTPS, and is the image in question on a post or page edited in the block editor? If either answer is no, the image was made on the server and this article does not apply to it.
- Ask who uploaded it and from what. Chrome or Edge on a desktop, dropped into the editor: browser path. Firefox, Safari, the media library screen, a product page, an automation: server path. That is the diagnosis for a watermark that is on some images and not others.
- Watch the network tab once. Upload an image into a post from Chrome with
the browser's developer tools open. Requests to
/wp/v2/media/{id}/sideloadare the thumbnails arriving from the browser; their absence means the server made them. The core team's own testing note suggests this check, and it is more reliable than thewindow.__clientSideMediaProcessingflag, which a plugin developer found set totruein Firefox as well. - Read each media plugin's "Tested up to" and changelog. Anything below 7.1 with a hook on thumbnail generation is a candidate; a changelog entry about client-side uploads is a plugin that has been through this already.
- If you need the old behaviour everywhere, there is one switch and it is
code.
add_filter( 'wp_client_side_media_processing_enabled', '__return_false' );in a small plugin or the theme's functions file turns the feature off for the whole site, and the handbook says "no other changes are needed". EWWW users have the same switch as a setting. There is no option in the admin.
That makes this a different kind of repair from the orders screen that changed in the same release: there is no single thing to fix, only an inventory to take - which plugins touch thumbnails, which have been updated, which screens the staff upload from - and then either an update, a filter, or a plugin replacement. That inventory is a bounded job with a price and the kind of website work we do.
The two roads will stay open. The note's author told a commenter in September that plugin authors "shouldn't need to worry about which flow (client or server) processed an image", because the end result "is the same" - which is true of the metadata and false of anything a plugin was supposed to do to the files in between. Mozilla's recorded position on the required header is positive, which its own tracker says is not a commitment to ship it, and the note's author has said Firefox intends to; WebKit's position is negative. So for the foreseeable future the browser on the uploader's desk decides which code runs on your server, and a site with more than one person uploading has both.
Sources
- Client-Side Media Processing in WordPress 7.1 - Make WordPress Core, published 22 July 2026, last modified 20 August 2026, read 12 September 2026. The feature description, the three hooks that never fire, the browser table, the feature-detection limits and the transparent fallback, both statements about plugins, the GIF handling, the disabling filter, and the comment exchange of 3 and 4 September 2026 quoted above.
- Client-side media architecture and Client-side media how-to - WordPress Block Editor Handbook, read 12 September 2026. The "intentionally left silent" explanation, the per-request hook sequence including the two passes of
wp_generate_attachment_metadata, thegenerate_sub_sizesparameter and its default, and the "no other changes are needed" note on disabling. - media.php and class-wp-rest-attachments-controller.php - WordPress core source at tag 7.1.0, read 12 September 2026. The HTTPS-or-localhost default, the block-editor-screen check before the isolation header, the Chromium 137 threshold, and the
generate_sub_sizesdefault oftrue. - class-wc-post-types.php - WooCommerce source, read 12 September 2026. The filter returning
falsefor theproductpost type onuse_block_editor_for_post_type. - Image Watermark and Easy Watermark - plugin sources from the WordPress.org repository, read 12 September 2026, with each plugin's directory page for version, last update and tested-up-to. The registration of the watermark callback inside the upload handler, the size loop, and the applied-watermarks list. Not run against a live site.
- Plugin changelogs read 12 September 2026 through the WordPress.org plugin information API: Imagify 2.3.3, EWWW Image Optimizer 8.7.6, WP Offload Media Lite 3.4.0. Tag dates from the repository's file timestamps.
- Smush and WP 7.1? - WordPress.org support forum, 25 and 26 August 2026, read 12 September 2026. The plugin author's reply on thumbnail sizes.
- Source search of the WordPress.org plugin directory for
add_filter( 'image_make_intermediate_size', run 12 September 2026 through a plugin-directory source-search service: 21 registrations in 21 plugins. - Gutenberg issue #82691 and wordpress-develop pull request #13446 - read 12 September 2026 through the GitHub API. The
crossorigininjection, its effect on offloaded media, and the open state of the core fix. Gutenberg issue #81895 for the indexed PNG regression and its reporter. - WordPress 7.1.1 RC1 is now available - Make WordPress Core, 10 September 2026, read 12 September 2026. The contents of the release candidate and the planned date of 17 September for 7.1.1.
- WordPress 7.1 "Mary Lou" - release announcement, 19 August 2026, read 12 September 2026, and Call for Testing: Client-Side Media Processing of 4 June 2026 for the suggested network-tab check.
- Document-Isolation-Policy - Chrome Platform Status, read 12 September 2026. Chrome 137 on desktop and 146 on Android, and the recorded positions of Mozilla and WebKit. Mozilla's position is recorded in standards-positions #1074, closed as positive on 10 August 2026; that repository states that a position is not a commitment to implement.
Site down, or broken since the last update? Fix S — $300, 2 business days, fixed price.
Get my quote in 24hWritten by the Fixmation team.