dgraph-io/badger · error
Invalid read: Len: %d read at:[%d:%d]
Error message
Invalid read: Len: %d read at:[%d:%d]
What it means
Read parses a key-value entry from the value log at the given value pointer: it reads the entry header (h.klen + h.vlen) and slices the value out of the fetched byte slice kv. If kv is shorter than the declared key+value length, the entry extends beyond the readable data — a truncated or corrupt vlog entry — so badger logs details and returns this error instead of garbage.
Source
Thrown at value.go:998
// Fetch checksum from the end of the buffer.
checksum := buf[len(buf)-crc32.Size:]
if hash.Sum32() != y.BytesToU32(checksum) {
runCallback(cb)
return nil, nil, y.Wrapf(y.ErrChecksumMismatch, "value corrupted for vp: %+v", vp)
}
}
var h header
headerLen := h.Decode(buf)
kv := buf[headerLen:]
if lf.encryptionEnabled() {
kv, err = lf.decryptKV(kv, vp.Offset)
if err != nil {
return nil, cb, err
}
}
if uint32(len(kv)) < h.klen+h.vlen {
vlog.db.opt.Errorf("Invalid read: vp: %+v", vp)
return nil, nil, fmt.Errorf("Invalid read: Len: %d read at:[%d:%d]",
len(kv), h.klen, h.klen+h.vlen)
}
return kv[h.klen : h.klen+h.vlen], cb, nil
}
// getUnlockCallback will returns a function which unlock the logfile if the logfile is mmaped.
// otherwise, it unlock the logfile and return nil.
func (vlog *valueLog) getUnlockCallback(lf *logFile) func() {
if lf == nil {
return nil
}
return lf.lock.RUnlock
}
// readValueBytes return vlog entry slice and read locked log file. Caller should take care of
// logFile unlocking.
func (vlog *valueLog) readValueBytes(vp valuePointer) ([]byte, *logFile, error) {
lf, err := vlog.getFileRLocked(vp)View on GitHub (pinned to 2a001d466f)
Solutions
- Restore the vlog files from a known-good backup; the truncated entry is unrecoverable from the log itself.
- Re-put affected keys from the application's source of truth so fresh entries are written at valid offsets.
- Rely on badger's vlog replay/recovery (it truncates to the last valid entry on open); ensure a version that does this and reopen cleanly.
- If caused by version mismatch, migrate with Stream/Backup into a fresh DB instead of opening old files in-place.
- Check disk health (SMART/fsck) and stop copying live DB directories; use DB.Backup or stopped-DB snapshots.
Example fix
// before: reading after a crash with a truncated vlog
val, err := txn.Get(key) // Invalid read: Len: 100 read at:[10:150]
// after: guard the read and rewrite the entry when corrupt
val, err := txn.Get(key)
if err != nil && strings.Contains(err.Error(), "Invalid read") {
regenerateAndPut(key) // rebuild value from app source of truth
} Defensive patterns
Strategy: fallback
Validate before calling
// Go: verify vlog files are non-truncated before open (size sanity)
func checkVlogIntegrity(dir string) error {
return filepath.Walk(dir, func(p string, fi os.FileInfo, err error) error {
if err == nil && strings.HasSuffix(p, ".vlog") && fi.Size() < 20 {
return fmt.Errorf("vlog %s suspiciously small/truncated", p)
}
return nil
})
} Type guard
func isInvalidReadErr(err error) bool {
return err != nil && strings.Contains(err.Error(), "Invalid read: Len:")
} Try / catch
item, err := txn.Get(key)
if err != nil && isInvalidReadErr(err) {
// corrupt/truncated vlog entry: fall back to app source of truth
log.Printf("corrupt vlog entry for %s: %v", key, err)
return regenerateValue(key)
} Prevention
- Enable opt.SyncWrites for durability against partial entries on crash.
- Never back up a live badger directory mid-write; stop the DB or use DB.Backup.
- Keep badger versions consistent between write and read of a data directory.
- Monitor disk health (SMART) and fsck after suspected corruption.
When it happens
Trigger: Reading a key whose vlog entry is cut short: vlog truncated by a crash before fsync, disk corruption, an entry overwritten via a bad valuePointer, or a vlog written by an incompatible badger version with a different header layout.
Common situations: Power loss with SyncWrites=false leaving a partial entry; backing up a vlog mid-write; bit rot or failing disk; opening vlogs from a different badger version.
Related errors
- Empty value: %+v
- Invalid value pointer offset: %d greater than current offset
- ErrNoRewrite
- ErrTruncateNeeded
- While setting banned keys: %w
AI-assisted analysis of dgraph-io/badger@2a001d466f (2026-09-05).
Data as JSON: /api/errors/9ff5f0d1dc91929a.
Report an issue: GitHub.