{"record":{"id":"16f61205de961295","repo":"hashicorp/nomad","slug":"rcp-stream-close-timeout-must-be-greater-than-zero","errorCode":null,"errorMessage":"rcp.stream_close_timeout must be greater than zero","messagePattern":"rcp\\.stream_close_timeout must be greater than zero","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"command/agent/config.go","lineNumber":968,"sourceCode":"\tif rpc.DialTimeout > 0 {\n\t\tresult.DialTimeout = rpc.DialTimeout\n\t}\n\treturn &result\n}\n\nfunc (r *RPCConfig) Validate() error {\n\tif r != nil {\n\t\tif r.AcceptBacklog < 0 {\n\t\t\treturn errors.New(\"rcp.accept_backlog interval must be greater than zero\")\n\t\t}\n\t\tif r.KeepAliveInterval < 0 {\n\t\t\treturn errors.New(\"rcp.keep_alive_interval must be greater than zero\")\n\t\t}\n\t\tif r.ConnectionWriteTimeout < 0 {\n\t\t\treturn errors.New(\"rcp.connection_write_timeout must be greater than zero\")\n\t\t}\n\t\tif r.StreamCloseTimeout < 0 {\n\t\t\treturn errors.New(\"rcp.stream_close_timeout must be greater than zero\")\n\t\t}\n\t\tif r.StreamOpenTimeout < 0 {\n\t\t\treturn errors.New(\"rcp.stream_open_timeout must be greater than zero\")\n\t\t}\n\t\tif r.DialTimeout < 0 {\n\t\t\treturn errors.New(\"rpc.dial_timeout must be greater than or equal to zero\")\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// RaftBoltConfig is used in servers to configure parameters of the boltdb\n// used for raft consensus.\ntype RaftBoltConfig struct {\n\t// NoFreelistSync toggles whether the underlying raft storage should sync its\n\t// freelist to disk within the bolt .db file. When disabled, IO performance\n\t// will be improved but at the expense of longer startup times.","sourceCodeStart":950,"sourceCodeEnd":986,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/command/agent/config.go#L950-L986","documentation":"Returned by RPCConfig.Validate() in command/agent/config.go when rpc.stream_close_timeout is negative. This timeout governs how long an RPC stream may remain open before being closed; only negative values are rejected at agent startup. The message's 'rcp.' prefix is a typo for 'rpc.'.","triggerScenarios":"Configuring `rpc { stream_close_timeout = -30s }` in agent config or constructing RPCConfig with a negative StreamCloseTimeout and invoking Validate() before starting the agent.","commonSituations":"Hand-edited HCL/JSON configs with sign typos; config generators producing negative durations; attempts to express 'never close' with a negative number instead of a very large duration or omitting the setting.","solutions":["Set rpc.stream_close_timeout to zero or a positive duration (e.g. \"5m\")","Omit the field to use the built-in default","Fix templating logic that could produce negative values"],"exampleFix":"// before\nrpc { stream_close_timeout = -5m }\n// after\nrpc { stream_close_timeout = 5m }","handlingStrategy":"validation","validationCode":"if cfg.RPC != nil && cfg.RPC.StreamCloseTimeout < 0 {\n\treturn fmt.Errorf(\"rpc.stream_close_timeout must be >= 0\")\n}","typeGuard":"func validStreamCloseTimeout(r *RPCConfig) bool {\n\treturn r == nil || r.StreamCloseTimeout >= 0\n}","tryCatchPattern":"if err := rpcCfg.Validate(); err != nil {\n\tif strings.Contains(err.Error(), \"stream_close_timeout\") {\n\t\trpcCfg.StreamCloseTimeout = 5 * time.Minute\n\t}\n\treturn err\n}","preventionTips":["Express 'long-lived streams' with a large positive duration, never a negative one","Add config schema checks to IaC that render rpc blocks","Keep an example rpc block in docs with only valid positive durations"],"tags":["config","validation","nomad-agent","rpc","timeout"],"backgroundTag":"invalid-agent-config-value","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"}