nostra13/Android-Universal-Image-Loader · error · IllegalArgumentException

availableMemoryPercent must be in range (0 < % < 100)

Error message

availableMemoryPercent must be in range (0 < % < 100)

What it means

ImageLoaderConfiguration.Builder.memoryCacheSizePercentage(int) accepts only values strictly between 0 and 100 (exclusive on both ends), throwing IllegalArgumentException otherwise. The percentage is applied to Runtime.getRuntime().maxMemory() to derive the byte budget; 0 would disable the cache and 100 would try to use the entire heap, both misconfigurations. The result is stored in memoryCacheSize and LruMemoryCache is used.

Source

Thrown at library/src/main/java/com/nostra13/universalimageloader/core/ImageLoaderConfiguration.java:380

				L.w(WARNING_OVERLAP_MEMORY_CACHE);
			}

			this.memoryCacheSize = memoryCacheSize;
			return this;
		}

		/**
		 * Sets maximum memory cache size (in percent of available app memory) for {@link android.graphics.Bitmap
		 * bitmaps}.<br />
		 * Default value - 1/8 of available app memory.<br />
		 * <b>NOTE:</b> If you use this method then
		 * {@link com.nostra13.universalimageloader.cache.memory.impl.LruMemoryCache LruMemoryCache} will be used as
		 * memory cache. You can use {@link #memoryCache(MemoryCache)} method to set your own implementation of
		 * {@link MemoryCache}.
		 */
		public Builder memoryCacheSizePercentage(int availableMemoryPercent) {
			if (availableMemoryPercent <= 0 || availableMemoryPercent >= 100) {
				throw new IllegalArgumentException("availableMemoryPercent must be in range (0 < % < 100)");
			}

			if (memoryCache != null) {
				L.w(WARNING_OVERLAP_MEMORY_CACHE);
			}

			long availableMemory = Runtime.getRuntime().maxMemory();
			memoryCacheSize = (int) (availableMemory * (availableMemoryPercent / 100f));
			return this;
		}

		/**
		 * Sets memory cache for {@link android.graphics.Bitmap bitmaps}.<br />
		 * Default value - {@link com.nostra13.universalimageloader.cache.memory.impl.LruMemoryCache LruMemoryCache}
		 * with limited memory cache size (size = 1/8 of available app memory)<br />
		 * <br />
		 * <b>NOTE:</b> If you set custom memory cache then following configuration option will not be considered:
		 * <ul>

View on GitHub (pinned to ba33ec64d0)

Solutions

  1. Pass an integer percent strictly inside (0,100): memoryCacheSizePercentage(25)
  2. Clamp user/remote input: Math.min(99, Math.max(1, pct))
  3. If you need exact bytes, use memoryCacheSize(bytes) instead

Example fix

// before
builder.memoryCacheSizePercentage((int) (0.25f * 100)); // fine, but common bug:
builder.memoryCacheSizePercentage(0); // or 100 -> throws

// after
builder.memoryCacheSizePercentage(25); // 25% of available memory
// clamped remote value:
builder.memoryCacheSizePercentage(Math.min(99, Math.max(1, remotePct)));
Defensive patterns

Strategy: validation

Validate before calling

int pct = Math.min(99, Math.max(1, requestedPercent));
builder.memoryCacheSizePercentage(pct);

Type guard

static boolean isValidMemoryPercent(int pct) {
    return pct > 0 && pct < 100;
}

Prevention

When it happens

Trigger: memoryCacheSizePercentage(0), (100), or (negative); passing a fraction like 0.25 (25 percent already divided by 100) instead of the integer 25.

Common situations: Confusing the API with fractional-style libraries and passing 0.25 -> truncates to 0; UI slider allowing endpoint values 0 or 100; remote-config percentage delivered as 100 for 'max'.

Related errors


AI-assisted analysis of nostra13/Android-Universal-Image-Loader@ba33ec64d0 (2026-08-14). Data as JSON: /api/errors/0465ab051590c782. Report an issue: GitHub.