hashicorp/nomad · error

node pool %q does not exist

Error message

node pool %q does not exist

What it means

validateVolumeForState also verifies that a volume's NodePool names an existing node pool; if the pool lookup returns nil, the request fails with this message. Additionally, when both NodeID and NodePool are set, the node's actual pool must match. This error covers the missing-pool case.

Source

Thrown at nomad/host_volume_endpoint.go:468

	var poolFromExistingNode string
	if vol.NodeID != "" {
		node, err := snap.NodeByID(nil, vol.NodeID)
		if err != nil {
			return err // should never hit, bail out
		}
		if node == nil {
			return fmt.Errorf("node %q does not exist", vol.NodeID)
		}
		poolFromExistingNode = node.NodePool
	}

	if vol.NodePool != "" {
		pool, err := snap.NodePoolByName(nil, vol.NodePool)
		if err != nil {
			return err // should never hit, bail out
		}
		if pool == nil {
			return fmt.Errorf("node pool %q does not exist", vol.NodePool)
		}
		if poolFromExistingNode != "" && poolFromExistingNode != pool.Name {
			return fmt.Errorf("node ID %q is not in pool %q", vol.NodeID, vol.NodePool)
		}
	}

	return nil
}

func (v *HostVolume) createVolume(vol *structs.HostVolume) error {

	method := "ClientHostVolume.Create"
	cReq := &cstructs.ClientHostVolumeCreateRequest{
		ID:                        vol.ID,
		Name:                      vol.Name,
		PluginID:                  vol.PluginID,
		Namespace:                 vol.Namespace,
		NodeID:                    vol.NodeID,

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. List pools with `nomad node pool list` and correct the name in the spec.
  2. Create the missing pool first (`nomad node pool apply <name> ...`).
  3. Omit node_pool if the volume should inherit the node's default pool.
  4. Ensure NodePool matches the pool the referenced node actually belongs to.

Example fix

// before
node_pool = "gpu-pool"  // no such pool
// after
nomad node pool list
node_pool = "compute"  # an existing pool
Defensive patterns

Strategy: validation

Validate before calling

pools, _, _ := client.Operator().NodePoolList(nil)
found := false
for _, p := range pools.Pools {
    if p.Name == vol.NodePool { found = true }
}
if !found { return fmt.Errorf("node pool %q does not exist", vol.NodePool) }

Type guard

func poolExists(name string, pools *api.NodePoolListResponse) bool {
    for _, p := range pools.Pools { if p.Name == name { return true } }
    return false
}

Try / catch

if strings.Contains(err.Error(), "node pool") && strings.Contains(err.Error(), "does not exist") {
    // create the pool or correct the node_pool field
}

Prevention

When it happens

Trigger: Submitting a host volume via Create or Register with vol.NodePool set to a pool that does not exist in the cluster (checked via snap.NodePoolByName).

Common situations: Typo in pool name; node pools introduced in newer Nomad but specs written for a different cluster's pool layout; pools deleted by automation; enterprise vs OSS differences in pool availability.

Related errors


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