dgraph-io/badger · error

Attempting to drop data in read-only mode.

Error message

Attempting to drop data in read-only mode.

What it means

This is a deliberate panic thrown by badger's prepareToDrop() when the database was opened with ReadOnly: true and a drop operation (DropAll/DropNamespace) is attempted. Dropping data requires flushing memtables and writing new state to disk, which is impossible in read-only mode, so the library fails fast instead of silently corrupting or refusing later.

Source

Thrown at db.go:1756

	}

	// Make all pending writes finish. The following will also close writeCh.
	db.closers.writes.SignalAndWait()
	db.opt.Infof("Writes flushed. Stopping compactions now...")
	return nil
}

func (db *DB) unblockWrite() {
	db.closers.writes = z.NewCloser(1)
	go db.doWrites(db.closers.writes)

	// Resume writes.
	db.blockWrites.Store(0)
}

func (db *DB) prepareToDrop() (func(), error) {
	if db.opt.ReadOnly {
		panic("Attempting to drop data in read-only mode.")
	}
	// In order prepare for drop, we need to block the incoming writes and
	// write it to db. Then, flush all the pending memtable. So that, we
	// don't miss any entries.
	if err := db.blockWrite(); err != nil {
		return func() {}, err
	}
	reqs := make([]*request, 0, 10)
	for {
		select {
		case r := <-db.writeCh:
			reqs = append(reqs, r)
		default:
			if err := db.writeRequests(reqs); err != nil {
				db.opt.Errorf("writeRequests: %v", err)
			}
			db.stopMemoryFlush()
			return func() {

View on GitHub (pinned to 2a001d466f)

Solutions

  1. Open the DB without ReadOnly: true before calling DropAll/DropNamespace
  2. Skip the drop for read-only handles (e.g. if opt.ReadOnly, return early instead of dropping)
  3. Use a separate writable connection for administrative operations like drops

Example fix

// before
db, err := badger.Open(badger.DefaultOptions(dir).WithReadOnly(true))
err = db.DropAll()

// after
db, err := badger.Open(badger.DefaultOptions(dir)) // writable
err = db.DropAll()
Defensive patterns

Strategy: validation

Validate before calling

if db.Opts().ReadOnly { /* skip drop or open writable DB */ }

Prevention

When it happens

Trigger: Calling db.DropAll() or db.DropNamespace() (or any API that funnels into db.prepareToDrop()) on a DB opened via badger.Open with opt.ReadOnly = true.

Common situations: A maintenance/admin script reusing a shared Open() helper that hardcodes ReadOnly: true; copying a DB-open config from a replica/backup-reader and then running destructive cleanup; CI jobs that mount the DB directory read-only and pass ReadOnly to match, then still try to drop data.

Related errors


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