WebP Troubleshooting: Fix Conversion and Display Issues

Diagnose and fix common WebP problems: broken images, CDN caching errors, conversion tool failures, and visible quality artefacts.

Most WebP problems fall into a small number of well-understood categories: browser compatibility gaps, CDN caching misconfiguration, conversion tool errors, and quality issues introduced during encoding. Work through the relevant section below to identify the root cause and apply the correct fix.

My WebP Images Show a Broken Image Icon in the Browser #

A broken image icon usually points to one of three causes: the browser doesn’t support WebP, the server is returning the wrong MIME type, or the file was corrupted in transit.

Step 1 — Verify the MIME Type Your Server Returns #

Run a HEAD request against the image URL and check the content-type header:

curl -I https://example.com/image.webp | grep content-type

The response must include content-type: image/webp. If it shows application/octet-stream or text/plain, the server is not recognising the .webp extension.

Step 2 — Register the MIME Type on Your Server #

Apache: add the following line to your .htaccess file or server configuration:

AddType image/webp .webp

Nginx: add the MIME type inside the types block in mime.types (or your nginx.conf):

image/webp webp;

Then reload Nginx: sudo nginx -s reload

Step 3 — Add a Fallback for Unsupported Browsers #

Wrap your WebP image in a <picture> element with a JPEG or PNG fallback so older browsers gracefully degrade:

<picture>
  <source srcset="image.webp" type="image/webp" />
  <img src="image.jpg" alt="Description of the image" />
</picture>

Confirm your browser’s WebP support at caniuse.com/webp. If you’re testing in a browser that doesn’t support WebP, the fallback should render — not a broken icon.

cwebp: “Error! Cannot Open Input File” #

This error means cwebp cannot locate or read the source file. Work through these checks in order.

Verify the file exists and check its path:

ls -la input.jpg

If the file is missing or the path is wrong, the command fails immediately. Use an absolute path if you’re unsure of the current working directory.

Check that the source format is supported. cwebp accepts JPEG, PNG, TIFF, and WebP as input. It does not accept:

  • GIF — use gif2webp instead:
    gif2webp animation.gif -o animation.webp
  • SVG — rasterise to PNG first using Inkscape or another tool, then convert to WebP.
  • HEIC / RAW — convert to TIFF or PNG first using an appropriate converter.

Passing an unsupported format to cwebp often produces the “cannot open input file” error rather than a clearer format-mismatch message. If the file exists, the format is the most likely culprit.

WebP File Is LARGER Than the Original JPEG #

This is a common surprise, and it has a specific cause: the source JPEG was already heavily compressed (quality below ~60), so it contains very little redundant data for WebP to remove. Re-encoding it at a high WebP quality setting produces a larger file.

Fix Option 1 — Lower the WebP Quality Target #

cwebp -q 75 input.jpg -o output.webp

Experiment with values between 70 and 80 until the output is smaller than the original without visible quality loss.

Fix Option 2 — Keep the Original JPEG #

If the JPEG is already small and perceptually acceptable, there is no benefit in converting it. Keep it as-is and skip WebP conversion for that asset.

Fix Option 3 — Work From the Original Source #

The fundamental cause is that you’re converting from a compressed intermediate. Go back to the highest-quality source available — a RAW file, lossless TIFF, or original PNG export — convert that to WebP, and compare the file sizes.

Build your pipeline to always convert from originals, never from previously compressed outputs. Store originals separately from your delivery assets so you can re-encode if you need a different format or quality level later.

CDN Is Serving JPEG to WebP-Supporting Browsers #

When a CDN caches an image response without considering the Accept header, it stores one version of the response and serves it to everyone — regardless of whether their browser requested WebP or JPEG.

Root Cause — Missing Vary: Accept Header #

Your origin server must tell the CDN that the response varies based on the Accept request header. Without this, the CDN treats all requests to the same URL as identical.

Fix — Add the Vary Header on Your Origin #

Apache:

<IfModule mod_headers.c>
  Header append Vary Accept
</IfModule>

Nginx:

add_header Vary Accept;

Cloudflare: enable Polish in the Speed settings for your zone. Cloudflare handles Vary: Accept and WebP serving automatically.

After adding the header, purge the CDN cache so the CDN fetches fresh copies from the origin with the correct Vary header in place.

Verify the Fix #

Send a request with an explicit WebP Accept header and check the response content-type:

curl -H 'Accept: image/webp,image/*,*/*;q=0.8' \
  -I https://cdn.example.com/photo.jpg

The response should include content-type: image/webp when WebP is accepted.

Images Look Noticeably Different / Have Artefacts After Conversion #

Visible artefacts after conversion are almost always caused by one of three things: quality set too low, conversion from an already-compressed source, or using lossy mode on content that needs lossless encoding.

Increase the quality setting — artefacts become visible below quality 70. For photographic content, target quality 80–85:

cwebp -q 82 input.png -o output.webp

Use lossless mode for non-photographic content — logos, screenshots, diagrams, and images with sharp edges or text encode better in lossless mode, which eliminates compression artefacts entirely:

cwebp -lossless input.png -o output.webp

Fix alpha channel edge artefacts — if you see fringing or artefacts along transparent edges, increase the alpha quality to its maximum value:

cwebp -alpha_q 100 input.png -o output.webp

Convert from the original, not from a compressed intermediate — if the source is a previously compressed JPEG, each compression pass compounds quality loss. Always convert from the highest-quality original available.

If you’re re-encoding a batch and want to experiment with quality settings without installing tools, our free online image converter lets you preview results directly in your browser.

Animated WebP Doesn’t Loop / Plays Only Once #

Animated WebP files store loop behaviour in the ANIM chunk. If the loop count is set to 1, the animation plays once and stops.

Inspect the current loop count:

webpinfo animation.webp

Look for the loop_count field in the ANIM chunk output. A value of 1 means play once; 0 means infinite loop.

Re-encode with an explicit infinite loop using img2webp and set -loop 0:

img2webp -loop 0 -d 100 frame1.png frame2.png frame3.png -o animation.webp

The -d flag sets the frame duration in milliseconds. Adjust it to match your original animation timing.

If you’re converting from an animated GIF, pass gif2webp -loop_compatibility to preserve the loop count from the original GIF metadata.

ImageMagick Reports “No Decode Delegate for This Image Format” for WebP #

This error means your ImageMagick installation was compiled without WebP support — specifically, without linking against libwebp.

Verify whether WebP support is present:

convert -list format | grep -i webp

A working installation outputs a line like WEBP* rw-. If nothing appears, WebP support is missing.

Install WebP Support — Ubuntu / Debian #

Install libwebp-dev and then reinstall or recompile ImageMagick:

sudo apt install libwebp-dev imagemagick

If the package manager version of ImageMagick still lacks WebP support, compile from source after installing libwebp-dev.

Install WebP Support — macOS (Homebrew) #

brew install webp imagemagick

Homebrew’s ImageMagick formula links against libwebp automatically.

Install WebP Support — Compile From Source #

Install libwebp-dev, then configure ImageMagick with WebP enabled:

./configure --with-webp
make
sudo make install

After installation, re-run the format check to confirm WEBP* rw- appears in the output.

next/image Is Not Serving WebP #

Next.js Image Optimisation serves WebP automatically to supporting browsers, but a few configuration issues can prevent this.

Check your next.config.js formats list — make sure image/webp is included in the formats array:

// next.config.js
module.exports = {
  images: {
    formats: ['image/avif', 'image/webp'],
  },
}

Verify the response headers in the browser — open DevTools → Network → filter by image requests. The content-type for an optimised image should be image/webp in a supporting browser. If it shows image/jpeg, the optimisation pipeline may not be running.

Check for custom loaders — if you’ve configured a custom loader via loader or loaderFile, ensure the loader explicitly supports WebP output. Third-party CDN loaders vary in their format support.

Static exports bypass Image Optimisation — running next export (or output: 'export' in Next.js 13+) generates a static site that cannot use the server-side Image Optimisation API. In this case, pre-convert your images to WebP during the build step, or route image requests through a CDN image transformation service such as Cloudinary, imgix, or Cloudflare Images.

After changing next.config.js, restart the dev server or trigger a production rebuild. Changes to the image configuration do not hot-reload.

When you suspect a WebP file is structurally malformed — for example, it’s failing to render in multiple tools — inspect it with webpinfo to get a summary of its internal chunks, dimensions, colour space, and any encoding errors:

webpinfo -summary image.webp

This is the fastest way to confirm whether a file is a valid WebP container before spending time on encoder settings or server configuration.

Was this page helpful?