{"record":{"id":"24db1eca5fa02b63","repo":"nostra13/Android-Universal-Image-Loader","slug":"keys-must-match-regex-a-z0-9-1-64-key","errorCode":null,"errorMessage":"keys must match regex [a-z0-9_-]{1,64}: \"{key}\"","messagePattern":"keys must match regex \\[a-z0-9_-\\](.+?): \"(.+?)\"","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"library/src/main/java/com/nostra13/universalimageloader/cache/disc/impl/ext/DiskLruCache.java","lineNumber":697,"sourceCode":"\t\t\tMap.Entry<String, Entry> toEvict = lruEntries.entrySet().iterator().next();\n\t\t\tremove(toEvict.getKey());\n\t\t}\n\t}\n\n\t/**\n\t * Closes the cache and deletes all of its stored values. This will delete\n\t * all files in the cache directory including files that weren't created by\n\t * the cache.\n\t */\n\tpublic void delete() throws IOException {\n\t\tclose();\n\t\tUtil.deleteContents(directory);\n\t}\n\n\tprivate void validateKey(String key) {\n\t\tMatcher matcher = LEGAL_KEY_PATTERN.matcher(key);\n\t\tif (!matcher.matches()) {\n\t\t\tthrow new IllegalArgumentException(\"keys must match regex [a-z0-9_-]{1,64}: \\\"\" + key + \"\\\"\");\n\t\t}\n\t}\n\n\tprivate static String inputStreamToString(InputStream in) throws IOException {\n\t\treturn Util.readFully(new InputStreamReader(in, Util.UTF_8));\n\t}\n\n\t/** A snapshot of the values for an entry. */\n\tpublic final class Snapshot implements Closeable {\n\t\tprivate final String key;\n\t\tprivate final long sequenceNumber;\n\t\tprivate File[] files;\n\t\tprivate final InputStream[] ins;\n\t\tprivate final long[] lengths;\n\n\t\tprivate Snapshot(String key, long sequenceNumber, File[] files, InputStream[] ins, long[] lengths) {\n\t\t\tthis.key = key;\n\t\t\tthis.sequenceNumber = sequenceNumber;","sourceCodeStart":679,"sourceCodeEnd":715,"githubUrl":"https://github.com/nostra13/Android-Universal-Image-Loader/blob/ba33ec64d0daaa881d35852460e78c58d086bc18/library/src/main/java/com/nostra13/universalimageloader/cache/disc/impl/ext/DiskLruCache.java#L679-L715","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\ncache.get(\"https://example.com/img.png\"); // IllegalArgumentException\n\n// after\nFileNameGenerator gen = new HashCodeFileNameGenerator();\nString key = gen.generate(\"https://example.com/img.png\"); // e.g. \"1a2b3c4d\"\ncache.get(key);","handlingStrategy":"validation","validationCode":"private static final Pattern LEGAL_KEY = Pattern.compile(\"[a-z0-9_-]{1,64}\");\n\nString key = fileNameGenerator.generate(uri);\nif (!LEGAL_KEY.matcher(key).matches()) {\n    key = Integer.toHexString(key.hashCode()); // or hash the key properly\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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)."],"tags":["disk-cache","lru","validation","file-naming","regex"],"backgroundTag":null,"analyzedSha":"ba33ec64d0daaa881d35852460e78c58d086bc18","analyzedAt":"2026-08-14T15:41:15.893Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}