hashicorp/nomad · error

plan exceeds max allocation

Error message

plan exceeds max allocation

What it means

AllocsFit returns this error when the number of allocations in the proposed plan exceeds the node's NodeMaxAllocs limit. Nomad enforces a per-node cap on total allocations so a node never schedules more placements than it can support, regardless of free resources.

Source

Thrown at nomad/structs/funcs.go:147

	if _, exists := a[nodeID][name]; !exists {
		return nil, false
	}

	return a[nodeID][name], true
}

// AllocsFit checks if a given set of allocations will fit on a node.
// The netIdx can optionally be provided if its already been computed.
// If the netIdx is provided, it is assumed that the client has already
// ensured there are no collisions. If checkDevices is set to true, we check if
// there is a device oversubscription.
func AllocsFit(node *Node, allocs []*Allocation, netIdx *NetworkIndex, checkDevices bool) (bool, string, *ComparableResources, error) {
	// Compute the allocs' utilization from zero
	used := new(ComparableResources)
	if node.NodeMaxAllocs != 0 {
		if node.NodeMaxAllocs < len(allocs) {
			return false, "max allocation exceeded", used, fmt.Errorf("plan exceeds max allocation")
		}
	}
	reservedCores := map[uint16]struct{}{}
	var coreOverlap bool

	hostVolumeClaims := map[string]int{}
	exclusiveHostVolumeClaims := []string{}

	// For each alloc, add the resources
	for _, alloc := range allocs {
		// Do not consider the resource impact of terminal allocations
		if alloc.ClientTerminalStatus() {
			continue
		}

		cr := alloc.AllocatedResources.Comparable()
		used.Add(cr)

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Reduce the number of allocations targeting that node (consolidate tasks, scale down replicas)
  2. Spread the workload across more client nodes by adding capacity or adjusting constraints
  3. Increase node.NodeMaxAllocs via the client config (client { max_allocs = N }) if hardware genuinely supports more
  4. Inspect placement failures in 'nomad job status' output to confirm the max-allocs cause

Example fix

// before (client config)
client {
}
// after
client {
  max_allocs = 200
}
Defensive patterns

Strategy: validation

Validate before calling

// go: pre-check proposed placement count against the node cap
if node.NodeMaxAllocs != 0 && currentAllocs+newAllocs > node.NodeMaxAllocs {
    return fmt.Errorf("node %s would exceed max_allocs (%d)", node.ID, node.NodeMaxAllocs)
}

Try / catch

fits, reason, used, err := structs.AllocsFit(node, allocs, netIdx, true)
if err != nil || !fits {
    log.Printf("placement rejected: %s (used %+v)", reason, used)
}

Prevention

When it happens

Trigger: Scheduler evaluation calls AllocsFit(node, allocs, netIdx, checkDevices) and len(allocs) > node.NodeMaxAllocs (with NodeMaxAllocs != 0); triggered during plan applier or test-fitting when packing many small tasks onto one node.

Common situations: Clusters running many tiny jobs (e.g. hundreds of one-task system/batch jobs) hitting the per-node allocation ceiling; nodes with high NodeMaxAllocs removed or default changed between Nomad versions causing 'max allocation exceeded' plan rejections.

Related errors


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