hashicorp/nomad · error

failed to open WAL store: %w

Error message

failed to open WAL store: %w

What it means

After creating the WAL directory, MigrateToWAL opens the destination with raftwal.Open(walDir). This error wraps any failure from that open, meaning a valid WAL store could not be initialized in the freshly created directory. On failure the source BoltDB store is closed and the partially created WAL directory is removed so a retry starts clean.

Source

Thrown at helper/raftutil/migrate.go:98

			Timeout: 5 * time.Second,
		},
		MsgpackUseNewTimeFormat: true,
	})
	if err != nil {
		return fmt.Errorf("failed to open BoltDB store: %w", err)
	}

	// Create the destination WAL store.
	if err := os.MkdirAll(walDir, 0o700); err != nil {
		src.Close()
		return fmt.Errorf("failed to create WAL directory: %w", err)
	}

	dst, err := raftwal.Open(walDir)
	if err != nil {
		src.Close()
		cleanupWAL(walDir)
		return fmt.Errorf("failed to open WAL store: %w", err)
	}

	// Copy logs.
	logProgress := make(chan string, 64)
	wg.Add(1)
	go drainProgress(logProgress, progress, &wg)
	if err := migrate.CopyLogs(ctx, dst, src, migrateBatchBytes, logProgress); err != nil {
		dst.Close()
		src.Close()
		cleanupWAL(walDir)
		return fmt.Errorf("failed to copy logs: %w", err)
	}

	// Copy stable store keys.
	stableProgress := make(chan string, 64)
	wg.Add(1)
	go drainProgress(stableProgress, progress, &wg)
	if err := migrate.CopyStable(ctx, dst, src, nil, nil, stableProgress); err != nil {

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Read the wrapped error (%w) — fix the underlying cause (usually ENOSPC or EIO) and re-run the migration.
  2. Confirm sufficient free disk space (preflight requires bolt size + 512 MiB, but space can be consumed concurrently).
  3. Remove any partially written <raftDir>/wal directory (cleanupWAL may have failed, e.g. on Windows) and retry.
  4. Check storage health (dmesg / smartctl) if the wrapped error is an I/O error.
Defensive patterns

Strategy: retry

Validate before calling

usage, err := disk.Usage(raftDir)
if err == nil && usage.Free < 512*1024*1024 {
    return fmt.Errorf("only %d bytes free; free space before migrating", usage.Free)
}

Try / catch

err := raftutil.MigrateToWAL(ctx, raftDir, progress)
if err != nil && strings.Contains(err.Error(), "failed to open WAL store") {
    // safe to retry: cleanupWAL already removed the partial directory
    os.RemoveAll(filepath.Join(raftDir, "wal"))
    err = raftutil.MigrateToWAL(ctx, raftDir, progress)
}

Prevention

When it happens

Trigger: raftwal.Open(walDir) returns an error: the WAL backend cannot initialize its segment files (disk full, I/O error), the directory was corrupted between creation and open, an incompatible/corrupt pre-existing WAL layout, or an internal raft-wal initialization error.

Common situations: Disk filled up between preflight checks and the open; underlying storage throwing I/O errors; a leftover/corrupt wal directory from a previous crashed run that os.MkdirAll happily accepted; raft-wal version incompatibility with existing segment files.

Related errors


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