bumptech/glide · error · IOException

Received unexpected drawable type for animated webp, failing

Error message

Received unexpected drawable type for animated webp, failing: {decoded}

What it means

IOException thrown by AnimatedWebpDecoder.decode() when ImageDecoder.decodeDrawable returns a non-AnimatedImageDrawable for a source classified as ANIMATED_WEBP. The decoder requires an AnimatedImageDrawable to expose frame looping; a still drawable is treated as a decode failure.

Source

Thrown at library/src/main/java/com/bumptech/glide/load/resource/drawable/AnimatedWebpDecoder.java:75

  }

  @Synthetic
  boolean handles(InputStream is) throws IOException {
    return isHandled(ImageHeaderParserUtils.getType(imageHeaderParsers, is, arrayPool));
  }

  private boolean isHandled(ImageType imageType) {
    return imageType == ImageType.ANIMATED_WEBP;
  }

  @Synthetic
  Resource<Drawable> decode(@NonNull Source source, int width, int height, @NonNull Options options)
      throws IOException {
    Drawable decoded =
        ImageDecoder.decodeDrawable(
            source, new DefaultOnHeaderDecodedListener(width, height, options));
    if (!(decoded instanceof AnimatedImageDrawable)) {
      throw new IOException(
          "Received unexpected drawable type for animated webp, failing: " + decoded);
    }
    return new AnimatedImageDrawableResource((AnimatedImageDrawable) decoded);
  }

  private static final class AnimatedImageDrawableResource implements Resource<Drawable> {
    /** A totally made up number of the number of frames we think are held in memory at once... */
    private static final int ESTIMATED_NUMBER_OF_FRAMES = 2;

    private final AnimatedImageDrawable imageDrawable;

    AnimatedImageDrawableResource(AnimatedImageDrawable imageDrawable) {
      this.imageDrawable = imageDrawable;
    }

    @NonNull
    @Override
    public Class<Drawable> getResourceClass() {

View on GitHub (pinned to eb14a895d8)

Solutions

  1. Fall back to .asBitmap() or the GIF-style pipeline on failure.
  2. Use .error() to chain a bitmap-based fallback request.
  3. Re-encode the WebP with a tool that guarantees animation frames.
  4. Restrict animated WebP loads to API levels where ImageDecoder reliably returns AnimatedImageDrawable (typically API 31+).

Example fix

// before
Glide.with(ctx).load(webpUri).into(img);
// after
Glide.with(ctx).load(webpUri)
  .error(Glide.with(ctx).asBitmap().load(webpUri))
  .into(img);
Defensive patterns

Strategy: fallback

Validate before calling

// Use the simpler .load(resId) or .asBitmap() path for WebP you suspect is still.
// Pre-classify with an ImageHeaderParser if available.

Try / catch

// Chain a bitmap fallback.
Glide.with(ctx).load(webpUri)
  .error(Glide.with(ctx).asBitmap().load(webpUri))
  .into(img);

Prevention

When it happens

Trigger: An ANIMATED_WEBP source decoded on a device whose ImageDecoder returns a BitmapDrawable (still) instead of AnimatedImageDrawable. Common on older API levels or OEM-modified decoders.

Common situations: Loading animated WebP on devices with broken ImageDecoder support for WebP animation. File misidentified as animated by the sniffing logic. AVIF/other format masquerading as WebP.

Related errors


AI-assisted analysis of bumptech/glide@eb14a895d8 (2026-08-14). Data as JSON: /api/errors/b796726c2e4c62c6. Report an issue: GitHub.