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

  1. Clear the prefix before calling: opt.Prefix = nil (or build a fresh IteratorOptions)
  2. Use iterator_options_t.ReuseIteratorOptions-style reset or construct opt inline per call
  3. 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

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


AI-assisted analysis of dgraph-io/badger@2a001d466f (2026-09-05). Data as JSON: /api/errors/0f1f3b8b0048f6a1. Report an issue: GitHub.