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
- Pass an integer percent strictly inside (0,100): memoryCacheSizePercentage(25)
- Clamp user/remote input: Math.min(99, Math.max(1, pct))
- 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
- Pass an integer percent (e.g. 25), not a fraction (0.25)
- Clamp user-facing or remote-config percentages to [1, 99]
- Use memoryCacheSize(bytes) when you need exact control
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.