{"record":{"id":"c754e202e27a9dc8","repo":"dgraph-io/badger","slug":"errdbclosed","errorCode":"ErrDBClosed","errorMessage":"DB Closed","messagePattern":"DB Closed","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"errors.go","lineNumber":116,"sourceCode":"\n\t// ErrEncryptionKeyMismatch is returned when the storage key is not\n\t// matched with the key previously given.\n\tErrEncryptionKeyMismatch = stderrors.New(\"Encryption key mismatch\")\n\n\t// ErrInvalidDataKeyID is returned if the datakey id is invalid.\n\tErrInvalidDataKeyID = stderrors.New(\"Invalid datakey id\")\n\n\t// ErrInvalidEncryptionKey is returned if length of encryption keys is invalid.\n\tErrInvalidEncryptionKey = stderrors.New(\"Encryption key's length should be\" +\n\t\t\"either 16, 24, or 32 bytes\")\n\t// ErrGCInMemoryMode is returned when db.RunValueLogGC is called in in-memory mode.\n\tErrGCInMemoryMode = stderrors.New(\"Cannot run value log GC when DB is opened in InMemory mode\")\n\n\t// ErrGCInReadOnlyMode is returned when db.RunValueLogGC is called in read-only mode.\n\tErrGCInReadOnlyMode = stderrors.New(\"Cannot run value log GC when DB is opened in ReadOnly mode\")\n\n\t// ErrDBClosed is returned when a get operation is performed after closing the DB.\n\tErrDBClosed = stderrors.New(\"DB Closed\")\n)\n","sourceCodeStart":98,"sourceCodeEnd":118,"githubUrl":"https://github.com/dgraph-io/badger/blob/2a001d466f6b71a917319a1db41f99860e16e269/errors.go#L98-L118","documentation":"ErrDBClosed is a sentinel error returned when a data operation is attempted after DB.Close() has completed. DB.get (db.go:791) returns it whenever db.IsClosed() is true, and the iterator code panics with it (iterator.go:464) if an iterator is used after close. The public View/Update transaction helpers surface it to callers of Get/Iterate after shutdown.","triggerScenarios":"Calling db.View(), db.Update(), txn.Get() or creating/using an iterator after db.Close() has returned; also background goroutines or deferred callbacks that outlive Close and keep touching the DB.","commonSituations":"Application shutdown racing with in-flight request handlers; background cache-refresh goroutines not cancelled before Close; accidental double-close followed by a read; tests calling View after Close.","solutions":["Ensure Close() is the last operation: cancel/clean up all goroutines, wait for in-flight requests (WaitGroup), then close.","Guard every access with db.IsClosed() before View/Update, or track closed state in application code.","Use errors.Is(err, badger.ErrDBClosed) to distinguish shutdown races from real failures and fail gracefully.","Fix double-close ordering bugs: never issue reads after a deferred Close in the same call path."],"exampleFix":"// before\ngo refreshCache(db)\ndb.Close()\n// after\nvar wg sync.WaitGroup\nwg.Add(1)\ngo func() { defer wg.Done(); refreshCache(db) }()\nwg.Wait()\ndb.Close()\n// and in read paths:\nif db.IsClosed() { return badger.ErrDBClosed }","handlingStrategy":"try-catch","validationCode":"if db.IsClosed() {\n    return badger.ErrDBClosed // or skip the read\n}\nerr := db.View(func(txn *badger.Txn) error { ... })","typeGuard":"func (w *SafeDB) usable() bool {\n    w.mu.RLock()\n    defer w.mu.RUnlock()\n    return !w.db.IsClosed()\n}","tryCatchPattern":"err := db.View(func(txn *badger.Txn) error { ... })\nif errors.Is(err, badger.ErrDBClosed) {\n    // DB is shutting down: log, drop the request or return a clean shutdown code\n    return nil\n}","preventionTips":["Stop all background goroutines and wait for in-flight requests (WaitGroup/errgroup) before calling Close().","Never read from a DB after a deferred Close in the same function scope.","Wrap *badger.DB in a wrapper exposing Close once and rejecting later operations (sync.Once + closed flag).","Check db.IsClosed() at the top of long-running loops that read from badger.","Use errors.Is(err, badger.ErrDBClosed) to distinguish shutdown races from real read failures."],"tags":["badger","closed-db","lifecycle","race-condition"],"backgroundTag":"use-after-close","analyzedSha":"2a001d466f6b71a917319a1db41f99860e16e269","analyzedAt":"2026-09-05T13:00:02.264Z","contentChangedAt":"2026-09-05T13:00:02.264Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}