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
- Always use a FileNameGenerator (HashCode, Md5) to derive keys: String key = fileNameGenerator.generate(imageUri).
- If you write a custom generator, normalize to lowercase [a-z0-9_-] and cap length at 64 (e.g. hash then hex-encode).
- 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
- Never use raw URIs/URLs as DiskLruCache keys — always derive them via a FileNameGenerator.
- Custom generators must emit lowercase [a-z0-9_-] only and <= 64 chars; hashing then hex-encoding guarantees it.
- Unit-test custom generators against the regex with adversarial inputs (uppercase, unicode, slashes, long strings).
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
- fileNameGenerator argument must be not null
- fileNameGenerator argument must be not null
- maxSize <= 0
- maxFileCount <= 0
- valueCount <= 0
AI-assisted analysis of nostra13/Android-Universal-Image-Loader@ba33ec64d0 (2026-08-14).
Data as JSON: /api/errors/24db1eca5fa02b63.
Report an issue: GitHub.