2026年11月12日
2026年11月12日
Fix EWWW Image Optimizer: Missing Tools, WebP Not Served, Bulk Stalls
This article is a localized edition of the Japanese original. Read the Japanese original
Most EWWW Image Optimizer (EWWW from here on) problems come down to one of three things: the server can't run the optimization tools, WebP files are created but nothing is set up to serve them, or bulk processing hits PHP's time limit. This article separates the causes by symptom and fixes them using only settings documented in the official docs (docs.ewww.io). Everything was checked against EWWW 8.9.x as of October 2026.
Symptoms and causes at a glance
| Symptom | Main causes | Where to look |
|---|---|---|
| The settings page says jpegtran, optipng, gifsicle or cwebp is "missing" | PHP's exec() is disabled, wp-content/ewww/ can't be created, or the tools aren't executable |
Steps 1 and 2 |
| WebP files exist, but browsers still receive JPEG/PNG | No WebP delivery method is selected, the .htaccess method is selected on Nginx, or a CDN such as Cloudflare caches the original image | Step 3 |
| Some images lose quality, or you don't want them optimized | No exclusions are configured | Step 4 |
| Bulk optimization (Bulk Optimize) stops partway through | Processing in the browser hits PHP's execution time or memory limit | Step 5 |
Step 1: Find out why the optimization tools don’t run
EWWW's free server-based optimization works by calling commands such as jpegtran, optipng, gifsicle and cwebp through PHP's exec(). According to the official description, the plugin places these tools in the wp-content/ewww/ folder automatically, so the web server user must be able to write to the wp-content folder.
Start by checking these three things on the server.
# 1) Is exec listed in disable_functions?
# (CLI and web can use different php.ini files, so also check the web value in phpinfo() output)
php -i | grep -i disable_functions
# 2) Does wp-content/ewww/ exist, and are the files executable (x)?
ls -l /var/www/html/wp-content/ewww/
# 3) Is the file system holding wp-content mounted noexec?
findmnt -T /var/www/html/wp-content -o TARGET,OPTIONS
- If
disable_functionsincludesexec, server-based optimization can't be used. Shared hosts often won't let you change this, so switch to the Compress API (cloud optimization) described below. - If
wp-content/ewww/doesn't exist, create the folder yourself or fix the permissions on wp-content (as the official docs advise). If you uploaded the tools by FTP, set your FTP client to binary transfer mode, or the files will be corrupted. - If
OPTIONSshowsnoexec, programs on that file system can't be executed.
When you're done, reopen "Settings" (設定 in the Japanese UI) → "EWWW Image Optimizer" in the WordPress admin and see whether the tool status has changed.
Step 2: Provide the tools, or switch to cloud optimization
Install packages on a server where you have root
On Ubuntu and Debian, these packages contain the tools.
sudo apt update
sudo apt install libjpeg-turbo-progs optipng gifsicle webp
which jpegtran optipng gifsicle cwebp
To make EWWW use the OS packages, add the following to wp-config.php above the "stop editing" line. This constant is the official setting that makes the plugin use system tools instead of the bundled ones. Note, however, that the official docs recommend the bundled tools and advise against this setting.
<?php
// Add above the "stop editing" line in wp-config.php
define( 'EWWW_IMAGE_OPTIMIZER_SKIP_BUNDLE', true );
Where PHP's open_basedir restricts executable paths, you can list the tool locations in EWWWIO_OPEN_BASEDIR, separated by colons (for example '/usr/bin/:/usr/local/bin/').
Use the Compress API on servers without exec
On a shared host where exec() is disabled, the tools won't run no matter where you put them. In that case, enter an API key for EWWW's Compress API (cloud optimization from ewww.io) on the settings page. What's free and what the paid plans include can change, so check the pricing page on ewww.io before you sign up.
Step 3: Fix WebP images that aren’t served
Turning on WebP conversion only creates separate files such as image.jpg.webp. To actually send WebP to browsers, you need to choose one of these delivery methods.
| Method | Best for | Notes |
|---|---|---|
| .htaccess rewrite rules (Apache / LiteSpeed) | Apache or LiteSpeed sites with .htaccess enabled | Requires mod_rewrite and mod_headers. Officially not recommended for sites behind Cloudflare |
| Nginx map rules | Nginx | The plugin can't write them, so you configure them by hand |
| JS WebP Rewriting | Sites behind a CDN or proxy | Rewrites URLs with JavaScript. May conflict with some themes or plugins |
<picture> WebP Rewriting |
Sites that want to avoid extra JavaScript | Doesn't work for CSS background images. Can break theme styling |
| Easy IO | Sites using a CDN | A paid image CDN service |
When the .htaccess method doesn’t work on Apache
- If the web server user can't write to
.htaccess, the rules aren't inserted. In that case, paste the rules shown on the settings page into.htaccessyourself. On multisite, they may need to go above the WordPress rules. - If mod_rewrite or mod_headers is disabled, you'll get an error. On Ubuntu's Apache, enable them with
sudo a2enmod rewrite headersand thensudo systemctl reload apache2. - If the test image in the WebP section of the settings page is a green WebP, delivery is working. If it stays a red PNG, reload the page and check again.
Serving WebP with Nginx
Nginx doesn't read .htaccess, so inserting the Apache rules has no effect. The method in the official docs edits three places.
# 1) Inside the http { } block (before server { })
map $http_accept $webp_suffix {
default "";
"~*webp" ".webp";
}
# 2) Add to /etc/nginx/mime.types if missing
# image/webp webp;
# 3) Inside the server { } block
location ~* ^.+\.(png|jpe?g|gif)$ {
add_header Vary Accept;
try_files $uri$webp_suffix $uri =404;
}
After editing, check the syntax with sudo nginx -t, then apply it with sudo systemctl reload nginx. To confirm, open the Network panel in your browser's developer tools and check that the image response has Content-Type image/webp.
# Check only the headers while posing as a WebP-capable browser (replace the URL with an image on your site)
curl -sI -H "Accept: image/webp" https://example.com/wp-content/uploads/2026/10/sample.jpg | grep -iE "content-type|vary"
If you use a CDN such as Cloudflare, it may cache the original JPEG without honoring Vary: Accept. After changing settings, purge the CDN cache as well.
Step 4: Exclude images and adjust quality
Set constants (official overrides)
Any EWWW setting can be overridden by defining a constant with the same name in wp-config.php. Don't wrap booleans or numbers in quotes.
<?php
// Add above the "stop editing" line in wp-config.php
// Exclude folders/files whose names partly match (no wildcards needed)
define( 'EWWW_IMAGE_OPTIMIZER_EXCLUDE_PATHS', array( 'portfolio', 'private-uploads' ) );
// Skip images smaller than this many bytes (0 = no limit)
define( 'EWWW_IMAGE_OPTIMIZER_SKIP_SIZE', 10240 );
// JPEG quality used for resizes, thumbnails and WebP (default 82)
define( 'EWWW_IMAGE_OPTIMIZER_JPG_QUALITY', 82 );
// WebP quality (default 75)
define( 'EWWW_IMAGE_OPTIMIZER_WEBP_QUALITY', 75 );
Settings defined as constants can no longer be changed in the admin screen.
Exclude by condition with a filter
To decide based on the file name, use the ewww_image_optimizer_bypass filter. The first argument is whether to skip the file, the second is the file's full path on the server, and returning true skips optimization for that file.
<?php
// Add to a child theme's functions.php or a code snippets plugin
add_filter( 'ewww_image_optimizer_bypass', function ( $bypass, $filename ) {
// Leave originals under uploads/originals/ untouched
if ( false !== strpos( $filename, '/uploads/originals/' ) ) {
return true;
}
return $bypass;
}, 10, 2 );
Step 5: Run bulk optimization with WP-CLI when it stalls
The Bulk Optimize screen under the "Media" (メディア in the Japanese UI) menu processes images through the browser, so with many images it can stop when it hits PHP's execution time or memory limit. If you have SSH and WP-CLI, running it from the command line is more stable.
# Run in the WordPress directory
cd /var/www/html
# Show usage
wp help ewwwio optimize
# Process the Media Library (same scope as the regular bulk optimizer); --noprompt skips confirmation
wp ewwwio optimize media --noprompt
# Wait 5 seconds between images to reduce server load
wp ewwwio optimize media 5 --noprompt
The main options in the official docs are:
--force: reprocesses everything, including images already optimized (same as "Force Re-optimize" on the bulk optimizer screen)--reset: rescans the images and starts over (not the same as--force)--noprompt: skips the confirmation after scanning. Use it when running from cron
Run long jobs inside screen or tmux so they keep going if your SSH session drops.
Cautions
- Back up
wp-content/uploads/before optimizing. Lossy compression and PNG-to-JPG conversion may not be reversible. - If you enable
EWWW_IMAGE_OPTIMIZER_DELETE_ORIGINALS, the original file is deleted after a format conversion, which can break old URLs in your posts. - Easy IO is a paid CDN service. Check ewww.io for current pricing and bandwidth terms.
- Running two image optimization plugins at once can process the same images twice or create conflicting WebP delivery rules. Keep only one.
Summary
- For "tools not found," check whether
exec()is available, whetherwp-content/ewww/exists with executable files, and whether the mount is noexec. Ifexec()is unavailable, switch to the Compress API - Converting to WebP doesn't serve WebP. Use .htaccess on Apache, map rules on Nginx, and JS or
<picture>rewriting behind a CDN - Set exclusions and quality with the official override constants in
wp-config.phpor theewww_image_optimizer_bypassfilter - Process large libraries with
wp ewwwio optimize media --noprompt
Related articles:
Questions about WordPress? The publisher of this site is based in Japan and replies in Japanese. Contact (Japanese)