dgraph-io/badger · error
opt.Prefix should be nil for NewKeyIterator.
Error message
opt.Prefix should be nil for NewKeyIterator.
What it means
NewKeyIterator iterates all versions of a single key by setting opt.Prefix itself from the key argument. Because Prefix is owned by NewKeyIterator, supplying your own non-empty opt.Prefix is ambiguous and Badger panics to prevent silent misconfiguration.
Source
Thrown at iterator.go:498
for i := 0; i < len(tables); i++ {
iters = append(iters, tables[i].sl.NewUniIterator(opt.Reverse))
}
iters = txn.db.lc.appendIterators(iters, &opt) // This will increment references.
res := &Iterator{
txn: txn,
iitr: table.NewMergeIterator(iters, opt.Reverse),
opt: opt,
readTs: txn.readTs,
}
return res
}
// NewKeyIterator is just like NewIterator, but allows the user to iterate over all versions of a
// single key. Internally, it sets the Prefix option in provided opt, and uses that prefix to
// additionally run bloom filter lookups before picking tables from the LSM tree.
func (txn *Txn) NewKeyIterator(key []byte, opt IteratorOptions) *Iterator {
if len(opt.Prefix) > 0 {
panic("opt.Prefix should be nil for NewKeyIterator.")
}
opt.Prefix = key // This key must be without the timestamp.
opt.prefixIsKey = true
opt.AllVersions = true
return txn.NewIterator(opt)
}
func (it *Iterator) newItem() *Item {
item := it.waste.pop()
if item == nil {
item = &Item{slice: new(y.Slice), txn: it.txn}
}
return item
}
// Item returns pointer to the current key-value pair.
// This item is only valid until it.Next() gets called.
func (it *Iterator) Item() *Item {View on GitHub (pinned to 2a001d466f)
Solutions
- Clear the prefix before calling: opt.Prefix = nil (or build a fresh IteratorOptions)
- Use iterator_options_t.ReuseIteratorOptions-style reset or construct opt inline per call
- Use txn.NewIterator(opt) instead if you actually want a manual prefix scan
Example fix
// before
opt.Prefix = []byte("user:")
it := txn.NewKeyIterator(key, opt) // panics
// after
opt.Prefix = nil
it := txn.NewKeyIterator(key, opt) Defensive patterns
Strategy: validation
Validate before calling
if len(opt.Prefix) > 0 { opt.Prefix = nil } // before NewKeyIterator
it := txn.NewKeyIterator(key, opt) Prevention
- Construct a fresh IteratorOptions per iterator call instead of sharing
- Clear Prefix when switching from NewIterator to NewKeyIterator
- Remember NewKeyIterator sets Prefix from the key argument itself
When it happens
Trigger: Calling txn.NewKeyIterator(key, opt) where opt was previously used with NewIterator and still carries a Prefix (or was explicitly configured with SetPrefix).
Common situations: Reusing a shared IteratorOptions struct across iterator types; copying iterator config from a prefix-scan helper into a key-version lookup.
Related errors
- Unclosed iterator at time of Txn.Discard.
- This transaction has been discarded. Create a new one
- DB Closed
- Cannot have 1 compactor. Need at least 2
- Cannot use badger in Disk-less mode with Dir or ValueDir set
AI-assisted analysis of dgraph-io/badger@2a001d466f (2026-09-05).
Data as JSON: /api/errors/0f1f3b8b0048f6a1.
Report an issue: GitHub.