dgraph-io/badger · error

This API can only be called in managed mode.

Error message

This API can only be called in managed mode.

What it means

NewStreamAt panics when the DB is NOT in managed mode. NewStreamAt reads at an explicit timestamp, which is only meaningful when the user controls commit timestamps (managed transactions); in normal mode it would return wrong/empty data, so the library refuses it with a panic.

Source

Thrown at stream.go:499

		db:        db,
		NumGo:     db.opt.NumGoroutines,
		LogPrefix: "Badger.Stream",
		MaxSize:   maxStreamSize,
	}
}

// NewStream creates a new Stream.
func (db *DB) NewStream() *Stream {
	if db.opt.managedTxns {
		panic("This API can not be called in managed mode.")
	}
	return db.newStream()
}

// NewStreamAt creates a new Stream at a particular timestamp. Should only be used with managed DB.
func (db *DB) NewStreamAt(readTs uint64) *Stream {
	if !db.opt.managedTxns {
		panic("This API can only be called in managed mode.")
	}
	stream := db.newStream()
	stream.readTs = readTs
	return stream
}

func BufferToKVList(buf *z.Buffer) (*pb.KVList, error) {
	var list pb.KVList
	err := buf.SliceIterate(func(s []byte) error {
		kv := new(pb.KV)
		if err := proto.Unmarshal(s, kv); err != nil {
			return err
		}
		list.Kv = append(list.Kv, kv)
		return nil
	})
	return &list, err
}

View on GitHub (pinned to 2a001d466f)

Solutions

  1. Open the DB in managed mode with badger.OpenManaged(opts) (or WithManagedTxns(true)) so NewStreamAt is valid
  2. If the DB is unmanaged, replace NewStreamAt with db.NewStream() which reads up to the latest visible timestamp
  3. Guard the call site on db.Opts().ManagedTxnsMode to pick the right stream constructor

Example fix

// before
db, _ := badger.Open(opts) // unmanaged
stream := db.NewStreamAt(ts) // panics
// after
db, _ := badger.OpenManaged(opts)
stream := db.NewStreamAt(db.MaxVersion())
Defensive patterns

Strategy: try-catch

Validate before calling

func canUseNewStreamAt(db *badger.DB) bool { return isManagedDB(db) } // true only when opened via OpenManaged / WithManagedTxns(true)

Type guard

func recoverPanicString(r interface{}) (string, bool) {
    s, ok := r.(string)
    return s, ok
}

Try / catch

func safeNewStreamAt(db *badger.DB, readTs uint64) (s *badger.Stream, err error) {
    defer func() {
        if r := recover(); r != nil {
            if msg, ok := r.(string); ok && strings.Contains(msg, "managed mode") {
                err = errors.New("db not in managed mode: use NewStream()")
                return
            }
            panic(r)
        }
    }()
    s = db.NewStreamAt(readTs)
    return
}

Prevention

When it happens

Trigger: Calling db.NewStreamAt(readTs) on a DB opened with badger.Open (unmanaged), directly or via helpers like getSampleKeys/StreamDB that assume a managed DB.

Common situations: Mixing OpenManaged and Open across environments (test uses managed, prod does not); using managed-only restore/stream utilities against a normal DB instance.

Related errors


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