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

unexpected journal line: {line}

Error message

unexpected journal line: {line}

What it means

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.

Source

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

			int lineCount = 0;
			while (true) {
				try {
					readJournalLine(reader.readLine());
					lineCount++;
				} catch (EOFException endOfJournal) {
					break;
				}
			}
			redundantOpCount = lineCount - lruEntries.size();
		} finally {
			Util.closeQuietly(reader);
		}
	}

	private void readJournalLine(String line) throws IOException {
		int firstSpace = line.indexOf(' ');
		if (firstSpace == -1) {
			throw new IOException("unexpected journal line: " + line);
		}

		int keyBegin = firstSpace + 1;
		int secondSpace = line.indexOf(' ', keyBegin);
		final String key;
		if (secondSpace == -1) {
			key = line.substring(keyBegin);
			if (firstSpace == REMOVE.length() && line.startsWith(REMOVE)) {
				lruEntries.remove(key);
				return;
			}
		} else {
			key = line.substring(keyBegin, secondSpace);
		}

		Entry entry = lruEntries.get(key);
		if (entry == null) {
			entry = new Entry(key);

View on GitHub (pinned to ba33ec64d0)

Solutions

  1. Treat this IOException from open() as 'cache invalid': wipe the directory contents and reopen to rebuild the journal.
  2. Ensure the cache directory is exclusively owned by the cache — no manual edits or other writers.
  3. Call flush()/close() on shutdown paths where possible so journals are left consistent.

Example fix

// before
DiskLruCache cache = DiskLruCache.open(dir, 1, 1, maxSize, maxFileCount);

// after
DiskLruCache cache;
try {
    cache = DiskLruCache.open(dir, 1, 1, maxSize, maxFileCount);
} catch (IOException e) {
    Util.deleteContents(dir); // malformed journal line: rebuild from scratch
    cache = DiskLruCache.open(dir, 1, 1, maxSize, maxFileCount);
}
Defensive patterns

Strategy: fallback

Try / catch

try {
    cache = DiskLruCache.open(dir, appVersion, 1, maxSize, maxFileCount);
} catch (IOException corruptJournal) {
    Util.deleteContents(dir);
    cache = DiskLruCache.open(dir, appVersion, 1, maxSize, maxFileCount); // fresh journal
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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