hashicorp/nomad · error

failed to close BoltDB store: %w

Error message

failed to close BoltDB store: %w

What it means

After the WAL store closes successfully, the source BoltDB store must also be closed before its file is renamed to a backup. This error wraps a failure closing the BoltDB handle — typically an fsync/flush failure on raft.db. The WAL directory is removed and the BoltDB file is left in place, so the migration can be retried, but it indicates possible trouble with the source storage.

Source

Thrown at helper/raftutil/migrate.go:141

	// Verify data integrity before finalizing.
	sendProgress(progress, "verifying migrated data")
	if err := verifyMigration(src, dst); err != nil {
		dst.Close()
		src.Close()
		cleanupWAL(walDir)
		return fmt.Errorf("data verification failed: %w", err)
	}

	// Close both stores before renaming files.
	if err := dst.Close(); err != nil {
		src.Close()
		cleanupWAL(walDir)
		return fmt.Errorf("failed to close WAL store: %w", err)
	}

	if err := src.Close(); err != nil {
		cleanupWAL(walDir)
		return fmt.Errorf("failed to close BoltDB store: %w", err)
	}

	// Rename the old BoltDB file to preserve it as a backup with timestamp.
	timestamp := time.Now().Format("20060102-150405")
	backupPath := fmt.Sprintf("%s.migrated.%s", boltPath, timestamp)
	if err := os.Rename(boltPath, backupPath); err != nil {
		return fmt.Errorf("migration succeeded but failed to rename %s to %s: %w",
			boltPath, backupPath, err)
	}

	sendProgress(progress, fmt.Sprintf("migration complete; old BoltDB file preserved at %s", backupPath))
	return nil
}

func sendProgress(progress chan<- string, msg string) {
	if progress != nil {
		select {
		case progress <- msg:

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Read the wrapped error and fix the storage issue (free space, replace failing disk).
  2. Run bolt check on raft.db to confirm the source store is still intact before retrying.
  3. Re-run MigrateToWAL once storage health is restored; the failed WAL directory has been removed.
  4. Take a filesystem-level copy of raft.db before further attempts if I/O errors persist.
Defensive patterns

Strategy: retry

Validate before calling

// verify source health before migrating:
cmd := exec.Command("bolt", "check", filepath.Join(raftDir, "raft.db"))
if err := cmd.Run(); err != nil {
    return fmt.Errorf("raft.db failed integrity check: %w", err)
}

Try / catch

err := raftutil.MigrateToWAL(ctx, raftDir, progress)
if err != nil && strings.Contains(err.Error(), "failed to close BoltDB store") {
    // raft.db left in place; check storage, run bolt check, then retry
}

Prevention

When it happens

Trigger: src.Close() returns an error: bbolt fails to flush pages or fsync the raft.db file on close (ENOSPC, EIO), or the file descriptor is in a bad state.

Common situations: Disk full at close time; failing disk or network storage returning I/O errors; raft.db previously damaged by a crash; extremely loaded host preventing flush completion.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/a5a5db8ec5d1a298. Report an issue: GitHub.