apache/druid · error · IllegalStateException
Expected footer checksum did not match actual checksum. Corr
Error message
Expected footer checksum did not match actual checksum. Corrupt or truncated file?
What it means
The footer carries an xxHash64 checksum of its own contents; FrameFileFooter recomputes it and compares. A mismatch means the footer bytes changed after writing — classic corruption/truncation — so the file cannot be trusted and reading is aborted.
Source
Thrown at processing/src/main/java/org/apache/druid/frame/file/FrameFileFooter.java:65
footerMemory.getCapacity() - FrameFileWriter.TRAILER_LENGTH,
FrameFileWriter.TRAILER_LENGTH,
ByteOrder.LITTLE_ENDIAN
);
this.numFrames = trailer.getInt(0);
this.numPartitions = trailer.getInt(Integer.BYTES);
int length = trailer.getInt(Integer.BYTES * 2L);
int expectedFooterChecksum = trailer.getInt(Integer.BYTES * 3L);
// Verify footer begins with MARKER_NO_MORE_FRAMES.
if (footerMemory.getByte(0) != FrameFileWriter.MARKER_NO_MORE_FRAMES) {
throw new IOE("File [%s] end marker not in expected location", "file");
}
// Verify footer checksum.
final int actualChecksum =
(int) footerMemory.xxHash64(0, footerMemory.getCapacity() - Integer.BYTES, FrameFileWriter.CHECKSUM_SEED);
if (expectedFooterChecksum != actualChecksum) {
throw new ISE("Expected footer checksum did not match actual checksum. Corrupt or truncated file?");
}
// Verify footer length.
if (length != FrameFileWriter.footerLength(numFrames, numPartitions)) {
throw new ISE("Expected footer length did not match actual footer length. Corrupt or truncated file?");
}
}
/**
* First frame of a given partition. Partitions beyond {@link #getNumPartitions()} are treated as empty: if provided,
* this method returns {@link #getNumFrames()}.
*/
public int getPartitionStartFrame(final int partition)
{
if (partition < 0) {
throw new IAE("Partition [%,d] out of bounds", partition);
} else if (partition >= numPartitions) {
// Frame might not have every partition, if some are empty.View on GitHub (pinned to 9b90983fd2)
Solutions
- Treat the file as unrecoverable and re-run the job that produced the frame file.
- Verify storage health if corruption recurs (disk errors, NFS/S3 consistency issues).
- Confirm the file transfer used binary mode and completed fully.
- Ensure only one process writes the file and readers wait for task completion.
Example fix
// before
FrameFile.open(suspectFile, maxMmapSize); // ISE on checksum mismatch
// after
if (checksumMatches(suspectFile, manifest.checksum())) {
FrameFile.open(suspectFile, maxMmapSize);
} else {
regenerateFrameFile(manifest); // re-run producing task
} Defensive patterns
Strategy: try-catch
Validate before calling
// verify the file end-to-end before use
try (java.io.RandomAccessFile raf = new java.io.RandomAccessFile(file, "r")) {
if (raf.length() != producerManifest.getSize()) throw new IllegalStateException("size mismatch");
} Try / catch
try {
FrameFile.open(file, maxMmapSize);
} catch (IllegalStateException e) {
if (e.getMessage().contains("checksum did not match")) {
regenerateFrameFile(file); // corruption is not recoverable in place
} else {
throw e;
}
} Prevention
- Keep checksums with produced frame files and verify after transfer/copy.
- Watch for recurring disk/medium errors in the storage backend.
- Ensure single-writer semantics — concurrent writers corrupt footers.
- Avoid modifying files under the Druid segment/output directories.
When it happens
Trigger: Opening a frame file whose footer bytes were altered (bit rot, partial write, edit after production) so the stored checksum no longer matches the recomputed hash.
Common situations: Disk/storage corruption; incomplete file transfer or download; file modified after task completion; concurrency where a reader sees a partially flushed file from a crashed writer.
Understand the failure class
Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.
Related errors
- File[%s] is too short (size[%,d])
- Negative-size footer. Corrupt or truncated file[%s]?
- Oversize footer. Corrupt or truncated file[%s]?
- File [%s] end marker not in expected location
- Expected footer length did not match actual footer length. C
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/0f0ef448c2a3817a.
Report an issue: GitHub.