hashicorp/nomad · error

number of schedulers should be between 0 and %d

Error message

number of schedulers should be between 0 and %d

What it means

convertServerConfig validates that the computed NumSchedulers is between 0 and runtime.NumCPU(). The value comes from server.num_schedulers in the agent config; Nomad enforces an upper bound of one scheduler per CPU core because schedulers are CPU-bound goroutines. Out-of-range values cause configuration to fail before server startup.

Source

Thrown at command/agent/agent.go:731

	conf.KEKProviderConfigs = agentConfig.KEKProviders

	if startTimeout := agentConfig.Server.StartTimeout; startTimeout != "" {
		dur, err := time.ParseDuration(startTimeout)
		if err != nil {
			return nil, fmt.Errorf("failed to parse start_timeout: %v", err)
		} else if dur <= time.Duration(0) {
			return nil, fmt.Errorf("start_timeout should be greater than 0s")
		}
		conf.StartTimeout = dur
	}

	// Ensure the passed number of scheduler is between the bounds of zero and
	// the number of CPU cores on the machine. The runtime CPU count object is
	// populated at process start time, so there is no overhead in calling the
	// function compared to saving the value.
	if conf.NumSchedulers < 0 || conf.NumSchedulers > runtime.NumCPU() {
		return nil, fmt.Errorf("number of schedulers should be between 0 and %d",
			runtime.NumCPU())
	}

	// If the operator has specified a client introduction server config block,
	// translate this into the internal server configuration object.
	if agentConfig.Server.ClientIntroduction != nil {
		if agentConfig.Server.ClientIntroduction.Enforcement != "" {
			conf.NodeIntroductionConfig.Enforcement = agentConfig.Server.ClientIntroduction.Enforcement
		}
		if agentConfig.Server.ClientIntroduction.DefaultIdentityTTL > 0 {
			conf.NodeIntroductionConfig.DefaultIdentityTTL = agentConfig.Server.ClientIntroduction.DefaultIdentityTTL
		}
		if agentConfig.Server.ClientIntroduction.MaxIdentityTTL > 0 {
			conf.NodeIntroductionConfig.MaxIdentityTTL = agentConfig.Server.ClientIntroduction.MaxIdentityTTL
		}
	}

	if err := conf.NodeIntroductionConfig.Validate(); err != nil {

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Set server.num_schedulers to a value between 0 and the host CPU count (check with nproc).
  2. Remove num_schedulers to let Nomad auto-size it to the CPU count.
  3. If running in containers, account for cgroup CPU limits and lower the value accordingly.

Example fix

// before
server {
  num_schedulers = 16  # on a 4-core machine
}
// after
server {
  num_schedulers = 4
}
Defensive patterns

Strategy: validation

Validate before calling

n := runtime.NumCPU()
if cfg.NumSchedulers < 0 || cfg.NumSchedulers > n {
  return fmt.Errorf("num_schedulers must be between 0 and %d, got %d", n, cfg.NumSchedulers)
}

Prevention

When it happens

Trigger: Setting server.num_schedulers to a negative number, or to a value greater than the machine's CPU core count (runtime.NumCPU()), during agent start or a config reload.

Common situations: Hard-coded num_schedulers from a larger machine copied to a smaller VM/container (e.g. 16 schedulers on a 4-core host); cgroup CPU limits making runtime.NumCPU() smaller than expected; hand-edited negative values.

Related errors


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