canopy-network/canopy · critical · ErrCloseDB
flush error: %v
Error message
flush error: %v
What it means
Store.Close discards any open transaction state and, if the store owns the underlying pebble DB, flushes memtables to disk before closing. If db.Flush() fails (disk error, corruption, I/O failure), the close is aborted with this wrapped error so the caller knows data may not be durable.
Source
Thrown at store/store.go:622
s.ss.Close()
s.sc = nil
s.Indexer.db.Close()
if s.writer != nil {
s.writer.Close()
}
}
// Close() discards the writer and closes an owned database connection
func (s *Store) Close() lib.ErrorI {
s.jobs.Wait()
s.mu.Lock()
defer s.mu.Unlock()
s.Discard()
if !s.ownsDB {
return nil
}
if err := s.db.Flush(); err != nil {
return ErrCloseDB(fmt.Errorf("flush error: %v", err))
}
if err := s.db.Close(); err != nil {
return ErrCloseDB(err)
}
return nil
}
// commitIDKey() returns the key for the commitID at a specific version
func (s *Store) commitIDKey(version uint64) []byte {
return append(stateCommitIDPrefix, lib.JoinLenPrefix(fmt.Appendf(nil, "%d", version))...)
}
// getCommitID() retrieves the CommitID value for the specified version from the database
func (s *Store) getCommitID(version uint64) (id lib.CommitID, err lib.ErrorI) {
var bz []byte
bz, err = NewTxn(s.Indexer.db.reader, nil, nil, false, false, true).Get(s.commitIDKey(version))
if err != nil {
returnView on GitHub (pinned to ee8197d91d)
Solutions
- Check the wrapped pebble error for the root cause (disk full, permission denied, corruption)
- Free disk space or fix filesystem permissions, then reopen and cleanly close the store again
- Check filesystem health (dmesg / SMART) if I/O errors persist
- If the error recurs during tests, point the store at a directory with sufficient space
Example fix
// before
defer store.Close() // error swallowed
// after
if err := store.Close(); err != nil {
log.Fatalf("store close failed, data may not be durable: %v", err)
} Defensive patterns
Strategy: try-catch
Validate before calling
if freeDisk(dataDir) < minHeadroom { return errors.New("insufficient disk space to close store cleanly") }
if !writable(dataDir) { return errors.New("data dir not writable") } Try / catch
if err := st.Close(); err != nil {
if strings.Contains(err.Error(), "flush error") {
log.Fatalf("store flush failed on close: %v — check disk space/health before restarting", err)
}
return err
} Prevention
- Monitor disk space and alert before it fills
- Always check the error from Close(); never discard it in defers
- Run filesystem health checks on nodes after any I/O error
- Give store data directories dedicated volumes with headroom
When it happens
Trigger: Calling Store.Close() (directly or via deferred close in tests/app shutdown) when the underlying pebble Flush returns an error — typically disk-full, permissions, or I/O errors at shutdown.
Common situations: Node shutdown while the disk is full or read-only; container filesystem issues; failing disk; closing a store in a test environment with a constrained temp directory.
Related errors
- flush before checkpoint: %w
- event not found
- quorum certificate not found
- ErrStoreGet
- nested transactions are not supported
AI-assisted analysis of canopy-network/canopy@ee8197d91d (2026-09-06).
Data as JSON: /api/errors/5f1396541226344e.
Report an issue: GitHub.