hashicorp/nomad · error

existing BoltDB raft store found at %s; run 'nomad operator

Error message

existing BoltDB raft store found at %s; run 'nomad operator raft migrate-backend %s' while the server is stopped to migrate to the WAL backend, then start the server again

What it means

Nomad's WAL-based Raft log store backend refuses to start if a legacy BoltDB raft store (raft.db) already exists in the raft directory, because switching backends silently would lose/dupe log data. The error instructs the operator to run the offline migration command.

Source

Thrown at nomad/server.go:1445

			return err
		}
		if err := os.WriteFile(raftVersionFilePath, []byte(raftVersionFileContent), 0644); err != nil {
			return fmt.Errorf("failed to write Raft version file: %v", err)
		}

		// Determine the raft log store backend to use.
		backend := LogStoreBackendBoltDB
		if s.config.RaftLogStoreConfig != nil && s.config.RaftLogStoreConfig.Backend != "" {
			backend = s.config.RaftLogStoreConfig.Backend
		}

		var store raftBackend
		switch backend {
		case LogStoreBackendWAL:
			// Check for an existing BoltDB store that needs migration.
			boltPath := filepath.Join(path, "raft.db")
			if _, statErr := os.Stat(boltPath); statErr == nil {
				return fmt.Errorf(
					"existing BoltDB raft store found at %s; "+
						"run 'nomad operator raft migrate-backend %s' while the server "+
						"is stopped to migrate to the WAL backend, then start the server again",
					boltPath, s.config.DataDir)
			}

			walDir := filepath.Join(path, "wal")
			if err := ensurePath(walDir, true); err != nil {
				return fmt.Errorf("failed to create WAL directory: %v", err)
			}

			walStore, walErr := s.openRaftWAL(walDir)
			if walErr != nil {
				return fmt.Errorf("failed to open WAL log store: %v", walErr)
			}
			store = walStore

		case LogStoreBackendBoltDB:

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Stop the server and run `nomad operator raft migrate-backend <data_dir>` to migrate raft.db to the WAL backend, then start the server
  2. If the old data is disposable, remove/rename <data_dir>/raft/raft.db (and understand cluster state implications — generally do not do this on a live cluster)
  3. Keep the older Nomad version if migration is not desired

Example fix

# before: server fails to start with existing raft.db
# after:
$ systemctl stop nomad
$ nomad operator raft migrate-backend /var/lib/nomad
$ systemctl start nomad
Defensive patterns

Strategy: validation

Validate before calling

if _, err := os.Stat(filepath.Join(dataDir, "raft", "raft.db")); err == nil {
    return fmt.Errorf("run 'nomad operator raft migrate-backend %s' before starting WAL backend", dataDir)
}

Try / catch

if err := server.Start(); err != nil {
    if strings.Contains(err.Error(), "existing BoltDB raft store found") {
        logger.Error("offline migration required; see error message for command")
    }
    return err
}

Prevention

When it happens

Trigger: setupRaft(): config selects RaftLogStoreBackend WAL (or the new default) while <raft path>/raft.db from a previous BoltDB-based server run is present.

Common situations: Upgrading Nomad from a version that defaulted to BoltDB to one that uses WAL; toggling raft log store config back and forth; restoring old data_dir under a new Nomad version.

Related errors


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