{"record":{"id":"e860ebdd26c51510","repo":"hashicorp/nomad","slug":"error-parsing-rpc-handshake-timeout-v","errorCode":null,"errorMessage":"error parsing rpc_handshake_timeout: %v","messagePattern":"error parsing rpc_handshake_timeout: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"command/agent/agent.go","lineNumber":596,"sourceCode":"\t\tif agentConfig.RPC.StreamOpenTimeout > 0 {\n\t\t\tconf.RPCSessionConfig.StreamOpenTimeout = agentConfig.RPC.StreamOpenTimeout\n\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","sourceCodeStart":578,"sourceCodeEnd":614,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/command/agent/agent.go#L578-L614","documentation":"The limits.rpc_handshake_timeout value is parsed with time.ParseDuration, which requires a Go duration string like \"5s\" or \"500ms\". If the value is absent-but-nonempty garbage or malformed (e.g. \"5\" with no unit, \"five seconds\"), ParseDuration fails and convertServerConfig returns this wrapped error, aborting agent startup or config reload.","triggerScenarios":"Setting limits { rpc_handshake_timeout = \"5\" } (missing unit), or any string that is not a valid Go duration (empty string, \"5 sec\", negative-looking typos like \"-5s\" handled separately by 1102) when starting or reloading a Nomad server.","commonSituations":"Users copying values from Prometheus/other tools that use plain numbers with implicit seconds; YAML/JSON configs where a numeric 5 gets stringified oddly; hand-edits adding the option without knowing Go duration syntax.","solutions":["Change the value to a valid Go duration string with a unit, e.g. rpc_handshake_timeout = \"5s\"","Remove the rpc_handshake_timeout line entirely to use the default","Check for stray whitespace, quotes, or locale-formatted numbers in the config value","Validate with nomad agent config / config validate before deploying if available"],"exampleFix":"// before\nlimits {\n  rpc_handshake_timeout = \"5\"\n}\n// after\nlimits {\n  rpc_handshake_timeout = \"5s\"\n}","handlingStrategy":"validation","validationCode":"// Go: pre-validate duration strings before writing the config\nfunc validDuration(s string) bool {\n    _, err := time.ParseDuration(s)\n    return s == \"\" || err == nil\n}\n// reject values like \"5\" early\nif !validDuration(cfg.Limits.RPCHandshakeTimeout) { ... }","typeGuard":"func isGoDuration(s string) bool {\n    _, err := time.ParseDuration(s)\n    return err == nil\n}","tryCatchPattern":"// wrap agent start to surface config errors clearly\nconf, err := convertServerConfig(agentConfig)\nif err != nil {\n    return fmt.Errorf(\"server config invalid: %w\", err)\n}","preventionTips":["Always include a unit (s, ms, m) in duration settings","Validate config with nomad validate in CI before rollout","Never paste bare numbers from tools with implicit-seconds semantics"],"tags":["config","duration-parsing","startup-validation","nomad"],"backgroundTag":"invalid-duration-format","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"}