{"record":{"id":"0f229f463505e82a","repo":"nostra13/Android-Universal-Image-Loader","slug":"unexpected-journal-line-line","errorCode":null,"errorMessage":"unexpected journal line: {line}","messagePattern":"unexpected journal line: (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"library/src/main/java/com/nostra13/universalimageloader/cache/disc/impl/ext/DiskLruCache.java","lineNumber":289,"sourceCode":"\t\t\tint lineCount = 0;\n\t\t\twhile (true) {\n\t\t\t\ttry {\n\t\t\t\t\treadJournalLine(reader.readLine());\n\t\t\t\t\tlineCount++;\n\t\t\t\t} catch (EOFException endOfJournal) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tredundantOpCount = lineCount - lruEntries.size();\n\t\t} finally {\n\t\t\tUtil.closeQuietly(reader);\n\t\t}\n\t}\n\n\tprivate void readJournalLine(String line) throws IOException {\n\t\tint firstSpace = line.indexOf(' ');\n\t\tif (firstSpace == -1) {\n\t\t\tthrow new IOException(\"unexpected journal line: \" + line);\n\t\t}\n\n\t\tint keyBegin = firstSpace + 1;\n\t\tint secondSpace = line.indexOf(' ', keyBegin);\n\t\tfinal String key;\n\t\tif (secondSpace == -1) {\n\t\t\tkey = line.substring(keyBegin);\n\t\t\tif (firstSpace == REMOVE.length() && line.startsWith(REMOVE)) {\n\t\t\t\tlruEntries.remove(key);\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else {\n\t\t\tkey = line.substring(keyBegin, secondSpace);\n\t\t}\n\n\t\tEntry entry = lruEntries.get(key);\n\t\tif (entry == null) {\n\t\t\tentry = new Entry(key);","sourceCodeStart":271,"sourceCodeEnd":307,"githubUrl":"https://github.com/nostra13/Android-Universal-Image-Loader/blob/ba33ec64d0daaa881d35852460e78c58d086bc18/library/src/main/java/com/nostra13/universalimageloader/cache/disc/impl/ext/DiskLruCache.java#L271-L307","documentation":"While replaying the journal at open() time, DiskLruCache.readJournalLine throws IOException when a journal line contains no space at all. Every valid journal line is 'OP key [args...]' (OP is CLEAN/DIRTY/READ/REMOVE), so a space-less line cannot be parsed and the journal is judged corrupt.","triggerScenarios":"An existing cache directory whose journal file contains a malformed line: empty-but-nonblank garbage, a line glued from a partial write, text editors or external tools having touched the journal, or filesystem corruption after a crash mid-append.","commonSituations":"Unclean process/device shutdown leaving a torn line in the journal; users or cleanup tools manually editing files inside the cache directory; SD-card corruption on the cache partition.","solutions":["Treat this IOException from open() as 'cache invalid': wipe the directory contents and reopen to rebuild the journal.","Ensure the cache directory is exclusively owned by the cache — no manual edits or other writers.","Call flush()/close() on shutdown paths where possible so journals are left consistent."],"exampleFix":"// before\nDiskLruCache cache = DiskLruCache.open(dir, 1, 1, maxSize, maxFileCount);\n\n// after\nDiskLruCache cache;\ntry {\n    cache = DiskLruCache.open(dir, 1, 1, maxSize, maxFileCount);\n} catch (IOException e) {\n    Util.deleteContents(dir); // malformed journal line: rebuild from scratch\n    cache = DiskLruCache.open(dir, 1, 1, maxSize, maxFileCount);\n}","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    cache = DiskLruCache.open(dir, appVersion, 1, maxSize, maxFileCount);\n} catch (IOException corruptJournal) {\n    Util.deleteContents(dir);\n    cache = DiskLruCache.open(dir, appVersion, 1, maxSize, maxFileCount); // fresh journal\n}","preventionTips":["Never edit, append to, or 'clean' files inside the cache directory manually.","Cache directories should have exactly one writer (the cache itself).","Close/flush the cache on normal shutdowns to keep journals consistent."],"tags":["disk-cache","lru","journal","corruption","io","parsing"],"backgroundTag":null,"analyzedSha":"ba33ec64d0daaa881d35852460e78c58d086bc18","analyzedAt":"2026-08-14T15:41:15.893Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}