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 {
		return

View on GitHub (pinned to ee8197d91d)

Solutions

  1. Check the wrapped pebble error for the root cause (disk full, permission denied, corruption)
  2. Free disk space or fix filesystem permissions, then reopen and cleanly close the store again
  3. Check filesystem health (dmesg / SMART) if I/O errors persist
  4. 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

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


AI-assisted analysis of canopy-network/canopy@ee8197d91d (2026-09-06). Data as JSON: /api/errors/5f1396541226344e. Report an issue: GitHub.