hashicorp/nomad · error

plan_rejection_tracker.node_window must be greater than 0

Error message

plan_rejection_tracker.node_window must be greater than 0

What it means

convertServerConfig in command/agent/agent.go validates the server's plan_rejection_tracker config block. When the tracker is configured, node_window must be a positive integer because it is the time window (likely in duration/string form used by the tracker) over which plan rejections are counted against node_threshold. A zero value would make the rejection tracker meaningless (division-by-window / no window to accumulate rejections), so the agent refuses to start or reload rather than run with a nonsensical tracker.

Source

Thrown at command/agent/agent.go:631

	// Set deployment rate limit
	if rate := agentConfig.Server.DeploymentQueryRateLimit; rate == 0 {
		conf.DeploymentQueryRateLimit = deploymentwatcher.LimitStateQueriesPerSecond
	} else if rate > 0 {
		conf.DeploymentQueryRateLimit = rate
	} else {
		return nil, fmt.Errorf("deploy_query_rate_limit must be greater than 0")
	}

	// Set plan rejection tracker configuration.
	if planRejectConf := agentConfig.Server.PlanRejectionTracker; planRejectConf != nil {
		if planRejectConf.Enabled != nil {
			conf.NodePlanRejectionEnabled = *planRejectConf.Enabled
		}
		conf.NodePlanRejectionThreshold = planRejectConf.NodeThreshold

		if planRejectConf.NodeWindow == 0 {
			return nil, fmt.Errorf("plan_rejection_tracker.node_window must be greater than 0")
		} else {
			conf.NodePlanRejectionWindow = planRejectConf.NodeWindow
		}
	}
	conf.PlanApplyPipeline = agentConfig.Server.PlanApplyPipeline

	// Add Enterprise license configs
	conf.LicenseConfig = &nomad.LicenseConfig{
		BuildDate:         agentConfig.Version.BuildDate,
		AdditionalPubKeys: agentConfig.Server.licenseAdditionalPublicKeys,
		LicenseEnvBytes:   agentConfig.Server.LicenseEnv,
		LicensePath:       agentConfig.Server.LicensePath,
		NonProduction:     agentConfig.Server.NonProduction,
	}

	// Add the search configuration
	if search := agentConfig.Server.Search; search != nil {
		conf.SearchConfig = &structs.SearchConfig{

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Set plan_rejection_tracker.node_window to a positive value (e.g. node_window = "10m") in the server block.
  2. If the tracker was not intentionally enabled, remove the plan_rejection_tracker block (or its enabled = true) entirely.
  3. Check templated/HCL-rendered config for an empty or 0 value being substituted for node_window.
  4. After fixing, restart the agent or run `nomad agent reload` / SIGHUP.

Example fix

// before (server.hcl)
server {
  plan_rejection_tracker {
    enabled        = true
    node_threshold = 100
    node_window    = 0
  }
}
// after
server {
  plan_rejection_tracker {
    enabled        = true
    node_threshold = 100
    node_window    = "10m"
  }
}
Defensive patterns

Strategy: validation

Validate before calling

// before deploying, validate the rendered HCL
// nomad validate server.hcl
// programmatic check on the parsed config:
if cfg.Server.PlanRejectionTracker != nil && cfg.Server.PlanRejectionTracker.NodeWindow == 0 {
    return fmt.Errorf("plan_rejection_tracker.node_window must be set to a positive value")
}

Prevention

When it happens

Trigger: Running `nomad agent -server` or `nomad agent reload` where the server config contains a plan_rejection_tracker block (enabled or with node_threshold set) but omits node_window, or sets node_window = 0. Also triggered on SIGHUP reload via handleReload since the same conversion runs.

Common situations: Copy-pasting a partial plan_rejection_tracker example that sets only enabled/threshold; operators enabling the tracker to mitigate plan-queue flooding and forgetting the window; config templating that injects an empty window value; upgrade paths where a previously optional field became required.

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/f073070e822e8b07. Report an issue: GitHub.