hashicorp/nomad · error

rpc.dial_timeout must be greater than or equal to zero

Error message

rpc.dial_timeout must be greater than or equal to zero

What it means

The agent config validation rejects a negative `rpc.dial_timeout`. The RPC layer uses this duration to time outbound dial attempts, and a negative value is meaningless, so Validate() fails fast with this error at startup instead of producing confusing runtime dial failures. Zero is explicitly allowed (treated as no override / immediate default handling).

Source

Thrown at command/agent/config.go:974

func (r *RPCConfig) Validate() error {
	if r != nil {
		if r.AcceptBacklog < 0 {
			return errors.New("rcp.accept_backlog interval must be greater than zero")
		}
		if r.KeepAliveInterval < 0 {
			return errors.New("rcp.keep_alive_interval must be greater than zero")
		}
		if r.ConnectionWriteTimeout < 0 {
			return errors.New("rcp.connection_write_timeout must be greater than zero")
		}
		if r.StreamCloseTimeout < 0 {
			return errors.New("rcp.stream_close_timeout must be greater than zero")
		}
		if r.StreamOpenTimeout < 0 {
			return errors.New("rcp.stream_open_timeout must be greater than zero")
		}
		if r.DialTimeout < 0 {
			return errors.New("rpc.dial_timeout must be greater than or equal to zero")
		}
	}

	return nil
}

// RaftBoltConfig is used in servers to configure parameters of the boltdb
// used for raft consensus.
type RaftBoltConfig struct {
	// NoFreelistSync toggles whether the underlying raft storage should sync its
	// freelist to disk within the bolt .db file. When disabled, IO performance
	// will be improved but at the expense of longer startup times.
	//
	// Default: false.
	NoFreelistSync bool `hcl:"no_freelist_sync"`
}

func (r *RaftBoltConfig) Copy() *RaftBoltConfig {

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Edit the agent config and set `rpc.dial_timeout` to a non-negative duration (e.g. "10s"), or remove the key to use the default.
  2. If the value comes from automation, fix the script/templating so it cannot emit a negative duration.
  3. If zero is desired behavior, set it explicitly to 0, which the validator accepts.

Example fix

// before (config.hcl)
rpc {
  dial_timeout = "-5s"
}

// after
rpc {
  dial_timeout = "10s"
}
Defensive patterns

Strategy: validation

Validate before calling

d, err := time.ParseDuration(cfg.RPC.DialTimeout)
if err != nil || d < 0 {
    return fmt.Errorf("rpc.dial_timeout must be a non-negative duration, got %q", cfg.RPC.DialTimeout)
}

Type guard

func validDialTimeout(d time.Duration) bool { return d >= 0 }

Prevention

When it happens

Trigger: Agent config contains `rpc { dial_timeout = <negative duration> }` (e.g. "-5s") and command/agent config parsing invokes the RPC block's Validate(), which checks `if r.DialTimeout < 0`.

Common situations: Typos with a leading minus sign in HCL/JSON config; scripts generating config by subtracting durations; copying a template and editing values incorrectly; unit tests injecting negative durations to check validation paths.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/1af05d47827a3555. Report an issue: GitHub.