{"record":{"id":"462b74638e469533","repo":"hashicorp/nomad","slug":"raft-snapshot-threshold-must-be-non-negative-got","errorCode":null,"errorMessage":"raft_snapshot_threshold must be non-negative, got %d","messagePattern":"raft_snapshot_threshold must be non-negative, got (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"command/agent/agent.go","lineNumber":271,"sourceCode":"\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\n\t}\n\tif len(agentConfig.Server.EnabledSchedulers) != 0 {\n\t\t// Convert to a set and require the core scheduler\n\t\tset := make(map[string]struct{}, 4)\n\t\tset[structs.JobTypeCore] = struct{}{}\n\t\tfor _, sched := range agentConfig.Server.EnabledSchedulers {\n\t\t\tset[sched] = struct{}{}","sourceCodeStart":253,"sourceCodeEnd":289,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/command/agent/agent.go#L253-L289","documentation":"In convertServerConfig, raft_snapshot_threshold was set to a value < 1; Raft requires a positive snapshot threshold, so agent config conversion fails and the server refuses to start with the invalid setting.","triggerScenarios":"Setting server { raft_snapshot_threshold = 0 } (or negative) during agent start or runtime reload.","commonSituations":"Trying to 'disable' snapshotting with 0; config templating emitting 0 for missing values; copying configs from other HashiCorp tools with different validation.","solutions":["Set raft_snapshot_threshold to a positive integer (default 8192).","Remove the stanza to use the Raft library default.","If snapshot frequency is a concern, adjust raft_snapshot_interval instead."],"exampleFix":"// before\nserver {\n  raft_snapshot_threshold = 0\n}\n// after\nserver {\n  raft_snapshot_threshold = 8192\n}","handlingStrategy":"validation","validationCode":"// Go: pre-validate\nif v := cfg.Server.RaftSnapshotThreshold; v != nil && *v < 1 {\n    return fmt.Errorf(\"raft_snapshot_threshold must be >= 1\")\n}","typeGuard":null,"tryCatchPattern":"conf, err := convertServerConfig(agentCfg)\nif err != nil {\n    if strings.Contains(err.Error(), \"raft_snapshot_threshold\") {\n        return fmt.Errorf(\"set raft_snapshot_threshold to a positive integer (default 8192): %w\", err)\n    }\n    return err\n}","preventionTips":["Omit raft_snapshot_threshold unless tuning; default 8192 is fine.","Never encode 'disabled' as 0 for Raft tunables.","Run config linting before reloads (SIGHUP) since validation also runs at reload time."],"tags":["nomad","raft","config"],"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"}