dgraph-io/badger · info
ErrKeyNotFound
ErrKeyNotFound
Error message
Key not found
What it means
ErrKeyNotFound is the sentinel returned by Txn.Get when no live version of the requested key is visible to the transaction's read timestamp. It also flows out of helpers like findFirstInvalidTxn. In Badger, absence of a key is an error return, not a nil item.
Source
Thrown at errors.go:24
package badger
import (
stderrors "errors"
"math"
)
const (
// ValueThresholdLimit is the maximum permissible value of opt.ValueThreshold.
ValueThresholdLimit = math.MaxUint16 - 16 + 1
)
var (
// ErrValueLogSize is returned when opt.ValueLogFileSize option is not within the valid
// range.
ErrValueLogSize = stderrors.New("Invalid ValueLogFileSize, must be in range [1MB, 2GB)")
// ErrKeyNotFound is returned when key isn't found on a txn.Get.
ErrKeyNotFound = stderrors.New("Key not found")
// ErrTxnTooBig is returned if too many writes are fit into a single transaction.
ErrTxnTooBig = stderrors.New("Txn is too big to fit into one request")
// ErrConflict is returned when a transaction conflicts with another transaction. This can
// happen if the read rows had been updated concurrently by another transaction.
ErrConflict = stderrors.New("Transaction Conflict. Please retry")
// ErrReadOnlyTxn is returned if an update function is called on a read-only transaction.
ErrReadOnlyTxn = stderrors.New("No sets or deletes are allowed in a read-only transaction")
// ErrDiscardedTxn is returned if a previously discarded transaction is reused.
ErrDiscardedTxn = stderrors.New("This transaction has been discarded. Create a new one")
// ErrEmptyKey is returned if an empty key is passed on an update function.
ErrEmptyKey = stderrors.New("Key cannot be empty")
// ErrInvalidKey is returned if the key has a special !badger! prefix,View on GitHub (pinned to 2a001d466f)
Solutions
- Treat err == ErrKeyNotFound as the 'absent' case, not a fatal failure
- If the key should exist, verify the writing transaction's Commit succeeded before reading
- In managed mode, ensure the read timestamp is >= the write's commit timestamp
- Confirm you opened the same directory (not a fresh/empty path)
Example fix
// before
item, err := tx.Get(key)
val, _ := item.ValueCopy(nil) // panics when err != nil
// after
item, err := tx.Get(key)
if err != nil {
if errors.Is(err, badger.ErrKeyNotFound) {
return nil // key absent
}
return err
} Defensive patterns
Strategy: try-catch
Try / catch
item, err := txn.Get(key)
if errors.Is(err, badger.ErrKeyNotFound) {
return handleAbsent(key)
}
if err != nil {
return err
} Prevention
- Never dereference item without checking err first
- Ensure the writer's Commit succeeded before reading the key
- In managed mode, use a read timestamp <= the write's commit ts
- Log/annotate ErrKeyNotFound with the key to ease debugging
When it happens
Trigger: tx.Get(k) on a key never written, deleted, written in an uncommitted transaction, or whose newest version is older than the reader's read timestamp (managed mode with a too-high ts); backup/restore code assuming a key exists (backup_test.go:165).
Common situations: Existence checks, read-after-write races before the writer commits, opening an empty/new DB directory, managed-mode timestamp mismatches.
Related errors
AI-assisted analysis of dgraph-io/badger@2a001d466f (2026-09-05).
Data as JSON: /api/errors/bd43812287f0b151.
Report an issue: GitHub.