{"record":{"id":"ceef56679436c8c5","repo":"hashicorp/nomad","slug":"rpc-handshake-timeout-must-be-0","errorCode":null,"errorMessage":"rpc_handshake_timeout must be >= 0","messagePattern":"rpc_handshake_timeout must be >= 0","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"command/agent/agent.go","lineNumber":598,"sourceCode":"\t\t}\n\t\tif agentConfig.RPC.DialTimeout > 0 {\n\t\t\tconf.RPCDialTimeout = agentConfig.RPC.DialTimeout\n\t\t}\n\t}\n\n\t// Set the TLS config\n\tconf.TLSConfig = agentConfig.TLSConfig\n\n\t// Setup telemetry related config\n\tconf.StatsCollectionInterval = agentConfig.Telemetry.collectionInterval\n\tconf.DisableDispatchedJobSummaryMetrics = agentConfig.Telemetry.DisableDispatchedJobSummaryMetrics\n\tconf.DisableQuotaUtilizationMetrics = agentConfig.Telemetry.DisableQuotaUtilizationMetrics\n\tconf.DisableRPCRateMetricsLabels = agentConfig.Telemetry.DisableRPCRateMetricsLabels\n\n\tif d, err := time.ParseDuration(agentConfig.Limits.RPCHandshakeTimeout); err != nil {\n\t\treturn nil, fmt.Errorf(\"error parsing rpc_handshake_timeout: %v\", err)\n\t} else if d < 0 {\n\t\treturn nil, fmt.Errorf(\"rpc_handshake_timeout must be >= 0\")\n\t} else {\n\t\tconf.RPCHandshakeTimeout = d\n\t}\n\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","sourceCodeStart":580,"sourceCodeEnd":616,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/command/agent/agent.go#L580-L616","documentation":"After parsing limits.rpc_handshake_timeout, convertServerConfig rejects negative durations: a negative handshake timeout is meaningless (a TCP/TLS handshake can't complete in negative time), so the agent refuses to start or reload rather than silently misconfiguring the RPC layer.","triggerScenarios":"Setting limits { rpc_handshake_timeout = \"-1s\" } (or any negative duration) in the server agent config and starting the agent, or applying it via a reload handled by handleReload.","commonSituations":"Operators trying to 'disable' the timeout with a negative value; templated configs where an interpolated variable resolves to a negative number; copy-paste mistakes from tuning scripts.","solutions":["Set a non-negative duration, e.g. rpc_handshake_timeout = \"5s\"","Remove the setting to use Nomad's default handshake timeout","If you wanted to disable the limit, check Nomad docs for the supported mechanism instead of using a negative value","Fix any template/variable producing a negative number"],"exampleFix":"// before\nlimits {\n  rpc_handshake_timeout = \"-1s\"\n}\n// after\nlimits {\n  rpc_handshake_timeout = \"5s\"\n}","handlingStrategy":"validation","validationCode":"// Go: reject negative durations before applying config\nd, err := time.ParseDuration(cfg.Limits.RPCHandshakeTimeout)\nif err != nil || d < 0 {\n    return errors.New(\"rpc_handshake_timeout must be a non-negative duration\")\n}","typeGuard":"func isNonNegativeDuration(s string) bool {\n    d, err := time.ParseDuration(s)\n    return err == nil && d >= 0\n}","tryCatchPattern":null,"preventionTips":["Never use negative values to 'disable' timeouts; remove the option instead","Clamp generated/templated values to >= 0","Add config lint checks for numeric sign on duration fields"],"tags":["config","validation","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"}