dgraph-io/badger · critical
Ptrs and Entries don't match: %+v
Error message
Ptrs and Entries don't match: %+v
What it means
writeToLSM verifies that each write request's entry list and its corresponding vlog pointer list are the same length, since every entry must map to exactly one pointer. A mismatch is an internal invariant violation, skipped only in InMemory mode where no pointers are produced.
Source
Thrown at db.go:829
if maxVs.Version < vs.Version {
maxVs = vs
}
}
return db.lc.get(key, maxVs, 0)
}
var requestPool = sync.Pool{
New: func() interface{} {
return new(request)
},
}
func (db *DB) writeToLSM(b *request) error {
// We should check the length of b.Prts and b.Entries only when badger is not
// running in InMemory mode. In InMemory mode, we don't write anything to the
// value log and that's why the length of b.Ptrs will always be zero.
if !db.opt.InMemory && len(b.Ptrs) != len(b.Entries) {
return fmt.Errorf("Ptrs and Entries don't match: %+v", b)
}
for i, entry := range b.Entries {
var err error
if entry.skipVlogAndSetThreshold(db.valueThreshold()) {
// Will include deletion / tombstone case.
err = db.mt.Put(entry.Key,
y.ValueStruct{
Value: entry.Value,
// Ensure value pointer flag is removed. Otherwise, the value will fail
// to be retrieved during iterator prefetch. `bitValuePointer` is only
// known to be set in write to LSM when the entry is loaded from a backup
// with lower ValueThreshold and its value was stored in the value log.
Meta: entry.meta &^ bitValuePointer,
UserMeta: entry.UserMeta,
ExpiresAt: entry.ExpiresAt,
})
} else {View on GitHub (pinned to 2a001d466f)
Solutions
- Report/fix the bug in the code constructing the request so len(Ptrs) == len(Entries)
- Never mutate b.Ptrs or b.Entries after submitting to writeRequests
- Upgrade badger — if hit on stock write APIs, it is a library bug
Defensive patterns
Strategy: type-guard
Validate before calling
if len(req.Ptrs) != len(req.Entries) {
return fmt.Errorf("bad request: %d ptrs vs %d entries", len(req.Ptrs), len(req.Entries))
} Type guard
func requestSane(r *request) bool { return len(r.Ptrs) == len(r.Entries) || inMemoryMode } Try / catch
if err := db.writeToLSM(req); err != nil {
if strings.Contains(err.Error(), "Ptrs and Entries don't match") {
log.Fatalf("internal bug: dump req entries=%d ptrs=%d", len(req.Entries), len(req.Ptrs))
}
} Prevention
- Never hand-construct request structs; use txns (Set/Delete/Commit)
- Don't mutate req.Ptrs/Entries after submission
- On badger forks, add this length check early with tests
When it happens
Trigger: Writing via db.Write, db.Commit, or writeRequests where the request's Ptrs and Entries slices diverged — effectively only reachable from internal bugs or custom code constructing request structs directly (e.g. in forks/tests).
Common situations: Patching badger internals or building manual write requests; concurrency bugs in code that mutates a request between vlog write and LSM write; InMemory mismatch confusion.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
AI-assisted analysis of dgraph-io/badger@2a001d466f (2026-09-05).
Data as JSON: /api/errors/87e130d97c818bf6.
Report an issue: GitHub.