dgraph-io/badger · error
ReadTs should not be retrieved for managed DB
Error message
ReadTs should not be retrieved for managed DB
What it means
This is a panic thrown by the oracle's readTs() when the DB is running with managed transactions enabled. In managed mode, read timestamps are supplied by the caller (via db.NewTransactionAt(ts, ...)), so fetching one internally via newTransaction is forbidden. The panic fires immediately before readTs would be computed.
Source
Thrown at txn.go:80
//
// WaterMarks must be 64-bit aligned for atomic package, hence we must use pointers here.
// See https://golang.org/pkg/sync/atomic/#pkg-note-BUG.
readMark: &y.WaterMark{Name: "badger.PendingReads"},
txnMark: &y.WaterMark{Name: "badger.TxnTimestamp"},
closer: z.NewCloser(2),
}
orc.readMark.Init(orc.closer)
orc.txnMark.Init(orc.closer)
return orc
}
func (o *oracle) Stop() {
o.closer.SignalAndWait()
}
func (o *oracle) readTs() uint64 {
if o.isManaged {
panic("ReadTs should not be retrieved for managed DB")
}
var readTs uint64
o.Lock()
readTs = o.nextTxnTs - 1
o.readMark.Begin(readTs)
o.Unlock()
// Wait for all txns which have no conflicts, have been assigned a commit
// timestamp and are going through the write to value log and LSM tree
// process. Not waiting here could mean that some txns which have been
// committed would not be read.
y.Check(o.txnMark.WaitForMark(context.Background(), readTs))
return readTs
}
func (o *oracle) nextTs() uint64 {
o.Lock()View on GitHub (pinned to 2a001d466f)
Solutions
- Replace db.NewTransaction/View/Update with db.NewTransactionAt(readTs, update) in managed mode, passing an appropriate read timestamp
- Obtain valid timestamps via db.Sequence-free APIs like the commit callbacks or an external allocator (e.g. Badger's oracle / watermarks)
- If managed mode is not needed, open the DB without WithManagedTxns(true)
- Audit all transaction-creation call sites (grep for NewTransaction/View/Update) when enabling managed txns
Example fix
// before (managed DB)
txn := db.NewTransaction(true)
// after (managed DB)
readTs := getReadTs() // from your timestamp allocator
if readTs == 0 {
db.View(func(txn *badger.Txn) error { ... }) // not allowed in managed mode
}
txn := db.NewTransactionAt(readTs, true) Defensive patterns
Strategy: validation
Validate before calling
if db.Opts().ManagedTxns { // must use NewTransactionAt
txn := db.NewTransactionAt(readTs, true)
} else {
txn := db.NewTransaction(true)
} Prevention
- Gate all transaction creation on a single helper that knows about managed mode
- Pass readTs explicitly through your service layer when managed txns are enabled
- Never call View/Update in managed mode
When it happens
Trigger: Calling db.NewTransaction(update=true) (or View/Update helpers) on a DB opened with WithManagedTxns(true); only db.NewTransactionAt(ts, update) and db.NewWriteBatchAt are valid transaction sources in managed mode.
Common situations: Enabling managed mode for Dgraph or custom timestamp control while leaving existing View()/Update() calls in place; library code (ORM layers, caches) that assumes standard transaction creation; toggling managedTxns in config without auditing all transaction creation sites.
Related errors
- This API can not be called in managed mode.
- This API can only be called in managed mode.
- BlockCacheSize should be set since compression/encryption ar
- Cannot use GetSequence with managedDB=true.
- Cannot use GetSequence in read-only mode.
AI-assisted analysis of dgraph-io/badger@2a001d466f (2026-09-05).
Data as JSON: /api/errors/c5655d4ce25af7e4.
Report an issue: GitHub.