hashicorp/nomad · error

raft_snapshot_interval must be greater than 5ms, got %q

Error message

raft_snapshot_interval must be greater than 5ms, got %q

What it means

In convertServerConfig, the configured raft_snapshot_interval duration parses but is below the 5ms minimum, so server startup fails rather than running Raft with a dangerously aggressive snapshot cadence.

Source

Thrown at command/agent/agent.go:264

		if raftMultiplier < 1 || raftMultiplier > MaxRaftMultiplier {
			return nil, fmt.Errorf("raft_multiplier cannot be %d. Must be between 1 and %d", *agentConfig.Server.RaftMultiplier, MaxRaftMultiplier)
		}
	}

	if vPtr := agentConfig.Server.RaftTrailingLogs; vPtr != nil {
		if *vPtr < 1 {
			return nil, fmt.Errorf("raft_trailing_logs must be non-negative, got %d", *vPtr)
		}
		conf.RaftConfig.TrailingLogs = uint64(*vPtr)
	}

	if vPtr := agentConfig.Server.RaftSnapshotInterval; vPtr != nil {
		dur, err := time.ParseDuration(*vPtr)
		if err != nil {
			return nil, err
		}
		if dur < 5*time.Millisecond {
			return nil, fmt.Errorf("raft_snapshot_interval must be greater than 5ms, got %q", *vPtr)
		}
		conf.RaftConfig.SnapshotInterval = dur
	}

	if vPtr := agentConfig.Server.RaftSnapshotThreshold; vPtr != nil {
		if *vPtr < 1 {
			return nil, fmt.Errorf("raft_snapshot_threshold must be non-negative, got %d", *vPtr)
		}
		conf.RaftConfig.SnapshotThreshold = uint64(*vPtr)
	}

	conf.RaftConfig.ElectionTimeout *= time.Duration(raftMultiplier)
	conf.RaftConfig.HeartbeatTimeout *= time.Duration(raftMultiplier)
	conf.RaftConfig.LeaderLeaseTimeout *= time.Duration(raftMultiplier)
	conf.RaftConfig.CommitTimeout *= time.Duration(raftMultiplier)

	if agentConfig.Server.NumSchedulers != nil {
		conf.NumSchedulers = *agentConfig.Server.NumSchedulers

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Set raft_snapshot_interval to a sane value >= 5ms (production default is 5s).
  2. Fix duration unit typos (e.g. "5s" instead of "5ms").
  3. Remove the stanza to use the default snapshot interval.

Example fix

// before
server {
  raft_snapshot_interval = "1ms"
}
// after
server {
  raft_snapshot_interval = "5s"
}
Defensive patterns

Strategy: validation

Validate before calling

// Go: pre-validate duration
if v := cfg.Server.RaftSnapshotInterval; v != nil {
    d, err := time.ParseDuration(*v)
    if err != nil || d < 5*time.Millisecond {
        return fmt.Errorf("raft_snapshot_interval %q invalid or < 5ms", *v)
    }
}

Try / catch

conf, err := convertServerConfig(agentCfg)
if err != nil {
    if strings.Contains(err.Error(), "raft_snapshot_interval") {
        return fmt.Errorf("use a duration >= 5ms (default 5s): %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Setting server { raft_snapshot_interval = "1ms" } or another sub-5ms duration, during agent start or SIGHUP reload.

Common situations: Aggressive snapshot tuning experiments; unit typos (writing 5ms intending 5m or 5s); generated configs from perf-testing tooling.

Related errors


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