bumptech/glide · error · IllegalStateException

Cannot obtain size for recycled Bitmap: {bitmap}[{width}x{he

Error message

Cannot obtain size for recycled Bitmap: {bitmap}[{width}x{height}] {config}

What it means

Thrown by Util.getBitmapByteSize(Bitmap) when bitmap.isRecycled() is true. The byte size of a Bitmap is read via getAllocationByteCount, whose return value silently changes from internal buffer size to rowBytes*height once the Bitmap is recycled, which would corrupt Glide's BitmapPool and memory-cache size accounting. The assert keeps cache sizes consistent.

Source

Thrown at library/src/main/java/com/bumptech/glide/util/Util.java:75

   * Returns the allocated byte size of the given bitmap.
   *
   * @see #getBitmapByteSize(android.graphics.Bitmap)
   * @deprecated Use {@link #getBitmapByteSize(android.graphics.Bitmap)} instead. Scheduled to be
   *     removed in Glide 4.0.
   */
  @Deprecated
  public static int getSize(@NonNull Bitmap bitmap) {
    return getBitmapByteSize(bitmap);
  }

  /** Returns the in memory size of the given {@link Bitmap} in bytes. */
  @TargetApi(Build.VERSION_CODES.KITKAT)
  public static int getBitmapByteSize(@NonNull Bitmap bitmap) {
    // The return value of getAllocationByteCount silently changes for recycled bitmaps from the
    // internal buffer size to row bytes * height. To avoid random inconsistencies in caches, we
    // instead assert here.
    if (bitmap.isRecycled()) {
      throw new IllegalStateException(
          "Cannot obtain size for recycled Bitmap: "
              + bitmap
              + "["
              + bitmap.getWidth()
              + "x"
              + bitmap.getHeight()
              + "] "
              + bitmap.getConfig());
    }
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
      // Workaround for KitKat initial release NPE in Bitmap, fixed in MR1. See issue #148.
      try {
        return bitmap.getAllocationByteCount();
      } catch (
          @SuppressWarnings("PMD.AvoidCatchingNPE")
          NullPointerException e) {
        // Do nothing.
      }

View on GitHub (pinned to eb14a895d8)

Solutions

  1. Never manually recycle a Bitmap that Glide loaded — Glide's BitmapPool manages recycling
  2. If you must recycle, only do so for Bitmaps you created yourself and that Glide has never seen
  3. Guard: if (!bitmap.isRecycled) Util.getBitmapByteSize(bitmap)
  4. Audit for double-recycle or external recycle of Glide-managed bitmaps (especially inListAdapter / onViewRecycled)

Example fix

// before
val bmp = (imageView.drawable as BitmapDrawable).bitmap
bmp.recycle()
Util.getBitmapByteSize(bmp) // IllegalStateException

// after — let Glide manage recycling
Glide.with(imageView).clear(imageView)
// or, for your own bitmaps:
if (!bmp.isRecycled) {
  Util.getBitmapByteSize(bmp)
}
Defensive patterns

Strategy: validation

Validate before calling

if (!bitmap.isRecycled) {
  val size = Util.getBitmapByteSize(bitmap)
} else {
  // bitmap already returned to pool; do not size it
}

Type guard

fun Bitmap.isUsable(): Boolean = !isRecycled

Prevention

When it happens

Trigger: Calling any code path that reads a Bitmap's byte size after Bitmap.recycle(): cache put/size accounting, BitmapPool.put, memory trimming that touches already-recycled bitmaps; manual recycling of a Bitmap still referenced by Glide.

Common situations: Calling imageView.drawable.bitmap.recycle() on a Bitmap that Glide still owns/manages; double-recycling; pool evictions racing with external recycle; passing a recycled Bitmap back into Glide via .load(bitmap).

Related errors


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