dgraph-io/badger · critical
invalid checksum length in footer. Data corrupted
Error message
invalid checksum length in footer. Data corrupted
What it means
After reading checksumLen from the footer's last 4 bytes, initIndex validates it: a negative value (uint32 >= 2^31 wrapped on 32-bit platforms) or a value larger than the bytes remaining before the footer position means the footer is garbage, so the table is rejected as corrupted.
Source
Thrown at table/table.go:442
// initIndex reads the index and populate the necessary table fields and returns
// first block offset
func (t *Table) initIndex() (*fb.BlockOffset, error) {
readPos := t.tableSize
// Read checksum len from the last 4 bytes.
if readPos < 4 {
return nil, errors.New("invalid table size in footer. Data corrupted")
}
readPos -= 4
buf := t.readNoFail(readPos, 4)
checksumLen := int(y.BytesToU32(buf))
// checksumLen == 0 is legal (a zero checksum marshals to nothing), so only
// reject negative lengths and lengths that don't fit in the bytes remaining
// before readPos. The < 0 guard catches a uint32 value >= 2^31 wrapping to a
// negative int on 32-bit platforms.
if checksumLen < 0 || checksumLen > readPos {
return nil, errors.New("invalid checksum length in footer. Data corrupted")
}
// Read checksum.
expectedChk := &pb.Checksum{}
readPos -= checksumLen
buf = t.readNoFail(readPos, checksumLen)
if err := proto.Unmarshal(buf, expectedChk); err != nil {
return nil, err
}
// Read index size from the footer.
if readPos < 4 {
return nil, errors.New("invalid table size in footer. Data corrupted")
}
readPos -= 4
buf = t.readNoFail(readPos, 4)
t.indexLen = int(y.BytesToU32(buf))
// A table always has at least one block, so a zero indexLen is alwaysView on GitHub (pinned to 2a001d466f)
Solutions
- Verify the file wasn't produced by a different Badger/LSM format version
- Re-transfer the file and compare checksums (md5sum) with the source
- Quarantine the corrupt table file and restore from backup
- Rebuild the DB via db.Load(db.Backup output) onto a fresh directory
Example fix
// before: mixing sst files from badger v2 dir into v3 data dir // after: migrate via export/import db.Backup(w, 0) // from old version DB newdb.Load(r, 0) // into fresh v3 directory
Defensive patterns
Strategy: validation
Validate before calling
if len(data) < 4 {
return errors.New("file too small to contain a footer")
}
chkLen := binary.LittleEndian.Uint32(data[len(data)-4:])
if int(chkLen) > len(data)-4 {
return errors.New("footer checksum length implausible — corrupt or wrong version")
} Prevention
- Use the same Badger version for writing and reading a data directory
- Verify md5/sha of files after transfer between machines
- Avoid manual edits or truncation of SST files
When it happens
Trigger: Opening a table whose last 4 bytes decode to an absurd checksum length — the file was written by a different/incompatible format version, was corrupted in transit, or its tail was overwritten.
Common situations: Mixing SST files across incompatible Badger versions; rsync/ftp in ASCII mode or with corruption; tail-sector disk damage; editing or truncating SST files manually.
Related errors
- invalid table size in footer. Data corrupted
- invalid index length in footer. Data corrupted
- initIndex crashed: %v %s
- invalid checksum length. Either the data is corrupted or the
- Unsupported compression type
AI-assisted analysis of dgraph-io/badger@2a001d466f (2026-09-05).
Data as JSON: /api/errors/364a3c8f22a4b57b.
Report an issue: GitHub.