dgraph-io/badger · error
Cannot use NewTransactionAt with managedDB=false. Use NewTra
Error message
Cannot use NewTransactionAt with managedDB=false. Use NewTransaction instead.
What it means
This panic is thrown by Badger's DB.NewTransactionAt when the database was opened without managed transaction mode (badger.DefaultOptions has managedDb=false / WithManagedTxns(false)). NewTransactionAt exists only for databases layered on Badger (e.g. Dgraph) that supply their own read timestamps; regular users must use NewTransaction. The library panics instead of returning an error because this is a programming/API-misuse error detected at the call site.
Source
Thrown at managed_db.go:25
// OpenManaged returns a new DB, which allows more control over setting
// transaction timestamps, aka managed mode.
//
// This is only useful for databases built on top of Badger (like Dgraph), and
// can be ignored by most users.
func OpenManaged(opts Options) (*DB, error) {
opts.managedTxns = true
return Open(opts)
}
// NewTransactionAt follows the same logic as DB.NewTransaction(), but uses the
// provided read timestamp.
//
// This is only useful for databases built on top of Badger (like Dgraph), and
// can be ignored by most users.
func (db *DB) NewTransactionAt(readTs uint64, update bool) *Txn {
if !db.opt.managedTxns {
panic("Cannot use NewTransactionAt with managedDB=false. Use NewTransaction instead.")
}
txn := db.newTransaction(update, true)
txn.readTs = readTs
return txn
}
// NewWriteBatchAt is similar to NewWriteBatch but it allows user to set the commit timestamp.
// NewWriteBatchAt is supposed to be used only in the managed mode.
func (db *DB) NewWriteBatchAt(commitTs uint64) *WriteBatch {
if !db.opt.managedTxns {
panic("cannot use NewWriteBatchAt with managedDB=false. Use NewWriteBatch instead")
}
wb := db.newWriteBatch(true)
wb.commitTs = commitTs
wb.txn.commitTs = commitTs
return wb
}View on GitHub (pinned to 2a001d466f)
Solutions
- Open the DB with WithManagedTxns(true): opts := badger.DefaultOptions(dir).WithManagedTxns(true); db, err := badger.Open(opts).
- If managed mode is not needed, replace NewTransactionAt(readTs, update) with db.NewTransaction(update) and drop the explicit readTs.
- Centralize DB opening in one helper so the managed flag and the At-style APIs stay consistent.
- Wrap the call in a function with defer/recover if you must probe behavior, though fixing the options is the real fix.
Example fix
// before opts := badger.DefaultOptions(dir) db, _ := badger.Open(opts) txn := db.NewTransactionAt(100, true) // after opts := badger.DefaultOptions(dir).WithManagedTxns(true) db, _ := badger.Open(opts) txn := db.NewTransactionAt(100, true) // ...or, without managed mode: txn := db.NewTransaction(true)
Defensive patterns
Strategy: validation
Validate before calling
if !db.Opts().ManagedTxns { // or track the option you passed to badger.Open
txn := db.NewTransaction(update)
} else {
txn := db.NewTransactionAt(readTs, update)
} Type guard
func isManagedDB(db *badger.DB, openedManaged bool) bool { return openedManaged } Try / catch
func safeNewTransactionAt(db *badger.DB, readTs uint64, update bool) (txn *badger.Txn, err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("NewTransactionAt requires managed mode: %v", r)
}
}()
txn = db.NewTransactionAt(readTs, update)
return
} Prevention
- Always set WithManagedTxns(true) in the single shared DB-open helper if any code uses At-style APIs
- Grep the codebase for NewTransactionAt/CommitAt/SetDiscardTs and verify each DB handle is opened in managed mode
- Prefer NewTransaction/NewWriteBatch unless you genuinely manage timestamps (e.g. building on Badger like Dgraph)
- Add a startup assertion that logs whether the DB is in managed mode before running timestamp-dependent tooling
When it happens
Trigger: Calling db.NewTransactionAt(readTs, update) on a DB opened with managedTxns disabled (the default). Callers seen in practice: compareTwo, fullScanDB, showKeysStats, numKeysManaged, produceKVs — any tool code that assumes managed mode but opened the DB with plain options.
Common situations: A developer copies code from Dgraph or a managed-mode example without switching to WithManagedTxns(true) when opening the DB; a utility written for managed DBs is pointed at a normal application DB; options are refactored and the managed flag is dropped.
Related errors
- cannot use NewWriteBatchAt with managedDB=false. Use NewWrit
- cannot use NewManagedWriteBatch with managedDB=false. Use Ne
- Cannot use CommitAt with managedDB=false. Use Commit instead
- Cannot use SetDiscardTs with managedDB=false.
- This API can not be called in managed mode.
AI-assisted analysis of dgraph-io/badger@2a001d466f (2026-09-05).
Data as JSON: /api/errors/28cbf05cd8e3d19f.
Report an issue: GitHub.