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

cacheMaxFileCount argument must be positive number

Error message

cacheMaxFileCount argument must be positive number

What it means

LruDiskCache's constructor throws IllegalArgumentException when cacheMaxFileCount is negative. As with cacheMaxSize, 0 is the documented 'unlimited' value (normalized to Integer.MAX_VALUE) and any negative count is rejected. The message wording ('must be positive number') is slightly off since 0 is legal.

Source

Thrown at library/src/main/java/com/nostra13/universalimageloader/cache/disc/impl/ext/LruDiskCache.java:91

	 * @param cacheDir          Directory for file caching
	 * @param reserveCacheDir   null-ok; Reserve directory for file caching. It's used when the primary directory isn't available.
	 * @param fileNameGenerator {@linkplain com.nostra13.universalimageloader.cache.disc.naming.FileNameGenerator
	 *                          Name generator} for cached files. Generated names must match the regex
	 *                          <strong>[a-z0-9_-]{1,64}</strong>
	 * @param cacheMaxSize      Max cache size in bytes. <b>0</b> means cache size is unlimited.
	 * @param cacheMaxFileCount Max file count in cache. <b>0</b> means file count is unlimited.
	 * @throws IOException if cache can't be initialized (e.g. "No space left on device")
	 */
	public LruDiskCache(File cacheDir, File reserveCacheDir, FileNameGenerator fileNameGenerator, long cacheMaxSize,
			int cacheMaxFileCount) throws IOException {
		if (cacheDir == null) {
			throw new IllegalArgumentException("cacheDir" + ERROR_ARG_NULL);
		}
		if (cacheMaxSize < 0) {
			throw new IllegalArgumentException("cacheMaxSize" + ERROR_ARG_NEGATIVE);
		}
		if (cacheMaxFileCount < 0) {
			throw new IllegalArgumentException("cacheMaxFileCount" + ERROR_ARG_NEGATIVE);
		}
		if (fileNameGenerator == null) {
			throw new IllegalArgumentException("fileNameGenerator" + ERROR_ARG_NULL);
		}

		if (cacheMaxSize == 0) {
			cacheMaxSize = Long.MAX_VALUE;
		}
		if (cacheMaxFileCount == 0) {
			cacheMaxFileCount = Integer.MAX_VALUE;
		}

		this.reserveCacheDir = reserveCacheDir;
		this.fileNameGenerator = fileNameGenerator;
		initCache(cacheDir, reserveCacheDir, cacheMaxSize, cacheMaxFileCount);
	}

	private void initCache(File cacheDir, File reserveCacheDir, long cacheMaxSize, int cacheMaxFileCount)

View on GitHub (pinned to ba33ec64d0)

Solutions

  1. Pass a positive count (e.g. 10000) or 0 for unlimited.
  2. Clamp computed counts with Math.max(0, n).
  3. Map sentinel values (-1) to 0 before construction.

Example fix

// before
int count = quota - usedFiles; // negative when over quota
new LruDiskCache(dir, null, gen, maxSize, count);

// after
int count = Math.max(0, quota - usedFiles);
new LruDiskCache(dir, null, gen, maxSize, count);
Defensive patterns

Strategy: validation

Validate before calling

int countArg = (cacheMaxFileCount >= 0) ? cacheMaxFileCount : 0; // 0 == unlimited
new LruDiskCache(dir, reserve, gen, maxSize, countArg);

Prevention

When it happens

Trigger: Calling new LruDiskCache(cacheDir, reserve, generator, maxSize, -1) or any negative count, e.g. from .diskCacheFileCount(-1) style configuration or a count computed as (limit - current) that underflowed.

Common situations: Using -1 as an 'unset' default in config objects and forwarding it directly; unit tests passing sentinel values; refactors that changed the parameter's type/order.

Related errors


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