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
- Open the DB without ReadOnly: true before calling DropAll/DropNamespace
- Skip the drop for read-only handles (e.g. if opt.ReadOnly, return early instead of dropping)
- 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
- Never hardcode ReadOnly: true in shared Open helpers used by admin code paths
- Route destructive operations (DropAll/DropNamespace) through a dedicated writable connection
- Panic in Go is not recoverable via error return — use recover() only at a top-level boundary if you must tolerate it
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
- Cannot use GetSequence in read-only mode.
- Cannot flatten in read-only mode.
- Cannot ban namespace in read-only mode.
- ErrReadOnlyTxn
- ErrWindowsNotSupported
AI-assisted analysis of dgraph-io/badger@2a001d466f (2026-09-05).
Data as JSON: /api/errors/ef04fda9fdecd485.
Report an issue: GitHub.