{"record":{"id":"d45de45dc6e73b66","repo":"hashicorp/nomad","slug":"deploy-query-rate-limit-must-be-greater-than-0","errorCode":null,"errorMessage":"deploy_query_rate_limit must be greater than 0","messagePattern":"deploy_query_rate_limit must be greater than 0","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"command/agent/agent.go","lineNumber":620,"sourceCode":"\n\t// Set max rpc conns; nil/0 == unlimited\n\t// Leave a little room for streaming RPCs\n\tminLimit := config.LimitsNonStreamingConnsPerClient + 5\n\tif agentConfig.Limits.RPCMaxConnsPerClient == nil || *agentConfig.Limits.RPCMaxConnsPerClient == 0 {\n\t\tconf.RPCMaxConnsPerClient = 0\n\t} else if limit := *agentConfig.Limits.RPCMaxConnsPerClient; limit <= minLimit {\n\t\treturn nil, fmt.Errorf(\"rpc_max_conns_per_client must be > %d; found: %d\", minLimit, limit)\n\t} else {\n\t\tconf.RPCMaxConnsPerClient = limit\n\t}\n\n\t// Set deployment rate limit\n\tif rate := agentConfig.Server.DeploymentQueryRateLimit; rate == 0 {\n\t\tconf.DeploymentQueryRateLimit = deploymentwatcher.LimitStateQueriesPerSecond\n\t} else if rate > 0 {\n\t\tconf.DeploymentQueryRateLimit = rate\n\t} else {\n\t\treturn nil, fmt.Errorf(\"deploy_query_rate_limit must be greater than 0\")\n\t}\n\n\t// Set plan rejection tracker configuration.\n\tif planRejectConf := agentConfig.Server.PlanRejectionTracker; planRejectConf != nil {\n\t\tif planRejectConf.Enabled != nil {\n\t\t\tconf.NodePlanRejectionEnabled = *planRejectConf.Enabled\n\t\t}\n\t\tconf.NodePlanRejectionThreshold = planRejectConf.NodeThreshold\n\n\t\tif planRejectConf.NodeWindow == 0 {\n\t\t\treturn nil, fmt.Errorf(\"plan_rejection_tracker.node_window must be greater than 0\")\n\t\t} else {\n\t\t\tconf.NodePlanRejectionWindow = planRejectConf.NodeWindow\n\t\t}\n\t}\n\tconf.PlanApplyPipeline = agentConfig.Server.PlanApplyPipeline\n\n\t// Add Enterprise license configs","sourceCodeStart":602,"sourceCodeEnd":638,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/command/agent/agent.go#L602-L638","documentation":"server.deploy_query_rate_limit controls the rate at which the server polls deployment watcher state queries. Zero is replaced by the built-in default (deploymentwatcher.LimitStateQueriesPerSecond), positive values are honored, but negative values are rejected by convertServerConfig because a negative rate limit is invalid.","triggerScenarios":"Setting server { deploy_query_rate_limit = -1 } (or any negative number) in the agent config and starting the agent, or applying it through a config reload.","commonSituations":"Operators trying to 'disable' deployment polling with a negative number; automation generating rate limits from calculations that can go negative; sign typos in hand-edited config.","solutions":["Set deploy_query_rate_limit to a positive number, or remove it to use the default","Fix the script/template that computed a negative rate","If the goal is less deployment polling load, lower the positive value rather than going negative"],"exampleFix":"// before\nserver {\n  deploy_query_rate_limit = -1\n}\n// after\nserver {\n  deploy_query_rate_limit = 50.0\n}","handlingStrategy":"validation","validationCode":"// Go: ensure rate limit is positive before applying\nif r := cfg.Server.DeploymentQueryRateLimit; r < 0 {\n    return errors.New(\"deploy_query_rate_limit must be greater than 0\")\n}","typeGuard":"func isPositiveRate(r float64) bool {\n    return r > 0\n}","tryCatchPattern":null,"preventionTips":["Omit deploy_query_rate_limit to accept the default instead of hand-tuning","Clamp computed/templated rates to a positive minimum","Use 0 (not negative) as the sentinel for 'use default' when generating configs"],"tags":["config","validation","rate-limit","nomad"],"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"}