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

keys must match regex [a-z0-9_-]{1,64}: "{key}"

Error message

keys must match regex [a-z0-9_-]{1,64}: "{key}"

What it means

IllegalArgumentException from DiskLruCache.validateKey, called by get/edit/remove. Keys become filenames (key.0, key.0.tmp) and journal tokens, so they are restricted to the regex [a-z0-9_-]{1,64}: lowercase alphanumerics, underscore, hyphen, max 64 chars. Any other key would corrupt the journal format or allow path separators.

Source

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

			Map.Entry<String, Entry> toEvict = lruEntries.entrySet().iterator().next();
			remove(toEvict.getKey());
		}
	}

	/**
	 * Closes the cache and deletes all of its stored values. This will delete
	 * all files in the cache directory including files that weren't created by
	 * the cache.
	 */
	public void delete() throws IOException {
		close();
		Util.deleteContents(directory);
	}

	private void validateKey(String key) {
		Matcher matcher = LEGAL_KEY_PATTERN.matcher(key);
		if (!matcher.matches()) {
			throw new IllegalArgumentException("keys must match regex [a-z0-9_-]{1,64}: \"" + key + "\"");
		}
	}

	private static String inputStreamToString(InputStream in) throws IOException {
		return Util.readFully(new InputStreamReader(in, Util.UTF_8));
	}

	/** A snapshot of the values for an entry. */
	public final class Snapshot implements Closeable {
		private final String key;
		private final long sequenceNumber;
		private File[] files;
		private final InputStream[] ins;
		private final long[] lengths;

		private Snapshot(String key, long sequenceNumber, File[] files, InputStream[] ins, long[] lengths) {
			this.key = key;
			this.sequenceNumber = sequenceNumber;

View on GitHub (pinned to ba33ec64d0)

Solutions

  1. Always use a FileNameGenerator (HashCode, Md5) to derive keys: String key = fileNameGenerator.generate(imageUri).
  2. If you write a custom generator, normalize to lowercase [a-z0-9_-] and cap length at 64 (e.g. hash then hex-encode).
  3. Validate keys up front with the same regex when interfacing with external key sources.

Example fix

// before
cache.get("https://example.com/img.png"); // IllegalArgumentException

// after
FileNameGenerator gen = new HashCodeFileNameGenerator();
String key = gen.generate("https://example.com/img.png"); // e.g. "1a2b3c4d"
cache.get(key);
Defensive patterns

Strategy: validation

Validate before calling

private static final Pattern LEGAL_KEY = Pattern.compile("[a-z0-9_-]{1,64}");

String key = fileNameGenerator.generate(uri);
if (!LEGAL_KEY.matcher(key).matches()) {
    key = Integer.toHexString(key.hashCode()); // or hash the key properly
}

Prevention

When it happens

Trigger: Passing a raw URL or arbitrary string as the key to cache.get()/edit()/remove() instead of a FileNameGenerator-produced name. Generators like HashCodeFileNameGenerator emit hex hashes that satisfy the pattern;Md5FileNameGenerator produces 32-char lowercase hex (also fine); a custom generator returning uppercase, dots, slashes, or >64 chars fails here.

Common situations: Writing custom code directly against LruDiskCache/DiskLruCache and using the image URI as the key; custom FileNameGenerator implementations that don't lowercase or truncate; generators based on Base64 or raw URIs.

Related errors


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