dgraph-io/badger · error

Cannot use SetDiscardTs with managedDB=false.

Error message

Cannot use SetDiscardTs with managedDB=false.

What it means

DB.SetDiscardTs declares a timestamp below which invalid/deleted versions may be garbage-collected from the LSM tree and value log. Because this affects timestamp bookkeeping, it is only valid with managed transactions; the library panics if db.opt.managedTxns is false. Nothing is applied to db.orc (oracle) when the guard fires.

Source

Thrown at managed_db.go:75

// can be ignored by most users.
func (txn *Txn) CommitAt(commitTs uint64, callback func(error)) error {
	if !txn.db.opt.managedTxns {
		panic("Cannot use CommitAt with managedDB=false. Use Commit instead.")
	}
	txn.commitTs = commitTs
	if callback == nil {
		return txn.Commit()
	}
	txn.CommitWith(callback)
	return nil
}

// SetDiscardTs sets a timestamp at or below which, any invalid or deleted
// versions can be discarded from the LSM tree, and thence from the value log to
// reclaim disk space. Can only be used with managed transactions.
func (db *DB) SetDiscardTs(ts uint64) {
	if !db.opt.managedTxns {
		panic("Cannot use SetDiscardTs with managedDB=false.")
	}
	db.orc.setDiscardTs(ts)
}

View on GitHub (pinned to 2a001d466f)

Solutions

  1. Open the DB with WithManagedTxns(true) before calling SetDiscardTs.
  2. If you cannot use managed mode, do not set a discard timestamp manually; rely on Badger's default garbage collection (db.RunValueLogGC with appropriate thresholds).
  3. Restrict SetDiscardTs to dedicated maintenance code paths that construct their own managed-mode DB handle.
  4. Document that discard-ts maintenance requires managed mode so operators don't reuse the script on ordinary DBs.

Example fix

// before
opts := badger.DefaultOptions(dir)
db, _ := badger.Open(opts)
db.SetDiscardTs(1000)
// after
opts := badger.DefaultOptions(dir).WithManagedTxns(true)
db, _ := badger.Open(opts)
db.SetDiscardTs(1000)
Defensive patterns

Strategy: validation

Validate before calling

if managedMode {
    db.SetDiscardTs(ts)
} else {
    // rely on default GC: db.RunValueLogGC(0.5) etc.
}

Type guard

func discardTsSupported(managedTxns bool) bool { return managedTxns }

Try / catch

func safeSetDiscardTs(db *badger.DB, ts uint64) (err error) {
    defer func() {
        if r := recover(); r != nil {
            err = fmt.Errorf("SetDiscardTs requires managed mode: %v", r)
        }
    }()
    db.SetDiscardTs(ts)
    return
}

Prevention

When it happens

Trigger: Calling db.SetDiscardTs(ts) on a DB opened without WithManagedTxns(true). The panic is raised at managed_db.go:75 before db.orc.setDiscardTs(ts) runs, so no GC watermark is changed.

Common situations: Running manual or scripted GC/compaction maintenance copied from managed-mode tooling; an operator applying Dgraph-style cleanup to a plain application DB; maintenance scripts that were written against a managed replica pointed at a normal DB file.

Related errors


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