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.

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.

Appendix: 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)