{"record":{"id":"360cfa86c19f71a3","repo":"hashicorp/nomad","slug":"raft-trailing-logs-must-be-non-negative-got-d","errorCode":null,"errorMessage":"raft_trailing_logs must be non-negative, got %d","messagePattern":"raft_trailing_logs must be non-negative, got (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"command/agent/agent.go","lineNumber":253,"sourceCode":"\t\tconf.DataDir = agentConfig.Server.DataDir\n\t}\n\tif agentConfig.Server.RaftProtocol != 0 {\n\t\tconf.RaftConfig.ProtocolVersion = raft.ProtocolVersion(agentConfig.Server.RaftProtocol)\n\t}\n\tif v := conf.RaftConfig.ProtocolVersion; v != 3 {\n\t\treturn nil, fmt.Errorf(\"raft_protocol must be 3 in Nomad v1.4 and later, got %d\", v)\n\t}\n\traftMultiplier := int(DefaultRaftMultiplier)\n\tif agentConfig.Server.RaftMultiplier != nil && *agentConfig.Server.RaftMultiplier != 0 {\n\t\traftMultiplier = *agentConfig.Server.RaftMultiplier\n\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)","sourceCodeStart":235,"sourceCodeEnd":271,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/command/agent/agent.go#L235-L271","documentation":"raft_trailing_logs controls how many log entries Raft keeps after a snapshot. convertServerConfig requires the value to be at least 1; a pointer-valued config option of 0 (or negative) is rejected despite the message saying 'non-negative'.","triggerScenarios":"Setting server { raft_trailing_logs = 0 } (or a negative number) then starting or reloading the agent.","commonSituations":"Attempting to disable trailing logs by setting 0; misreading the doc thinking 0 disables the feature; automated config generators emitting 0 for unset values.","solutions":["Set raft_trailing_logs to a positive integer (e.g. 10000, the default).","Remove the stanza to use the Raft default.","If intent was 'fewer retained logs', tune raft_snapshot_threshold/interval instead."],"exampleFix":"// before\nserver {\n  raft_trailing_logs = 0\n}\n// after\nserver {\n  raft_trailing_logs = 10000\n}","handlingStrategy":"validation","validationCode":"// Go: pre-validate\nif v := cfg.Server.RaftTrailingLogs; v != nil && *v < 1 {\n    return fmt.Errorf(\"raft_trailing_logs must be >= 1\")\n}","typeGuard":null,"tryCatchPattern":"conf, err := convertServerConfig(agentCfg)\nif err != nil {\n    if strings.Contains(err.Error(), \"raft_trailing_logs\") {\n        return fmt.Errorf(\"set raft_trailing_logs to a positive integer: %w\", err)\n    }\n    return err\n}","preventionTips":["Never set raft_trailing_logs to 0; omit it to use the default (10000).","Ensure config generators emit omit/absent instead of 0 for unset ints.","Test config rendering against a real `nomad agent` startup in CI."],"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"}