{"record":{"id":"b893301e1412abf0","repo":"hashicorp/nomad","slug":"raft-snapshot-interval-must-be-greater-than-5ms-g","errorCode":null,"errorMessage":"raft_snapshot_interval must be greater than 5ms, got %q","messagePattern":"raft_snapshot_interval must be greater than 5ms, got %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"command/agent/agent.go","lineNumber":264,"sourceCode":"\t\tif raftMultiplier < 1 || raftMultiplier > MaxRaftMultiplier {\n\t\t\treturn nil, fmt.Errorf(\"raft_multiplier cannot be %d. Must be between 1 and %d\", *agentConfig.Server.RaftMultiplier, MaxRaftMultiplier)\n\t\t}\n\t}\n\n\tif vPtr := agentConfig.Server.RaftTrailingLogs; vPtr != nil {\n\t\tif *vPtr < 1 {\n\t\t\treturn nil, fmt.Errorf(\"raft_trailing_logs must be non-negative, got %d\", *vPtr)\n\t\t}\n\t\tconf.RaftConfig.TrailingLogs = uint64(*vPtr)\n\t}\n\n\tif vPtr := agentConfig.Server.RaftSnapshotInterval; vPtr != nil {\n\t\tdur, err := time.ParseDuration(*vPtr)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif dur < 5*time.Millisecond {\n\t\t\treturn nil, fmt.Errorf(\"raft_snapshot_interval must be greater than 5ms, got %q\", *vPtr)\n\t\t}\n\t\tconf.RaftConfig.SnapshotInterval = dur\n\t}\n\n\tif vPtr := agentConfig.Server.RaftSnapshotThreshold; vPtr != nil {\n\t\tif *vPtr < 1 {\n\t\t\treturn nil, fmt.Errorf(\"raft_snapshot_threshold must be non-negative, got %d\", *vPtr)\n\t\t}\n\t\tconf.RaftConfig.SnapshotThreshold = uint64(*vPtr)\n\t}\n\n\tconf.RaftConfig.ElectionTimeout *= time.Duration(raftMultiplier)\n\tconf.RaftConfig.HeartbeatTimeout *= time.Duration(raftMultiplier)\n\tconf.RaftConfig.LeaderLeaseTimeout *= time.Duration(raftMultiplier)\n\tconf.RaftConfig.CommitTimeout *= time.Duration(raftMultiplier)\n\n\tif agentConfig.Server.NumSchedulers != nil {\n\t\tconf.NumSchedulers = *agentConfig.Server.NumSchedulers","sourceCodeStart":246,"sourceCodeEnd":282,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/command/agent/agent.go#L246-L282","documentation":"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.","triggerScenarios":"Setting server { raft_snapshot_interval = \"1ms\" } or another sub-5ms duration, during agent start or SIGHUP reload.","commonSituations":"Aggressive snapshot tuning experiments; unit typos (writing 5ms intending 5m or 5s); generated configs from perf-testing tooling.","solutions":["Set raft_snapshot_interval to a sane value >= 5ms (production default is 5s).","Fix duration unit typos (e.g. \"5s\" instead of \"5ms\").","Remove the stanza to use the default snapshot interval."],"exampleFix":"// before\nserver {\n  raft_snapshot_interval = \"1ms\"\n}\n// after\nserver {\n  raft_snapshot_interval = \"5s\"\n}","handlingStrategy":"validation","validationCode":"// Go: pre-validate duration\nif v := cfg.Server.RaftSnapshotInterval; v != nil {\n    d, err := time.ParseDuration(*v)\n    if err != nil || d < 5*time.Millisecond {\n        return fmt.Errorf(\"raft_snapshot_interval %q invalid or < 5ms\", *v)\n    }\n}","typeGuard":null,"tryCatchPattern":"conf, err := convertServerConfig(agentCfg)\nif err != nil {\n    if strings.Contains(err.Error(), \"raft_snapshot_interval\") {\n        return fmt.Errorf(\"use a duration >= 5ms (default 5s): %w\", err)\n    }\n    return err\n}","preventionTips":["Use the production default of 5s unless profiling says otherwise.","Double-check duration units (ms vs s vs m) in configs.","Validate rendered durations with time.ParseDuration in tests."],"tags":["nomad","raft","config","duration"],"backgroundTag":"config-value-out-of-range","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}