hashicorp/nomad · error
node %q does not exist
Error message
node %q does not exist
What it means
validateVolumeForState checks that a volume's NodeID references a real node in the state snapshot. When NodeID is set but no node with that ID exists, Create and Register fail with this message. This prevents registering volumes bound to nodes the cluster has never seen or has since forgotten.
Source
Thrown at nomad/host_volume_endpoint.go:457
}
err = vol.ValidateUpdate(existing)
if err != nil {
return existing, fmt.Errorf("validating volume %q update failed: %v", vol.ID, err)
}
}
return existing, nil
}
// validateVolumeForState ensures that any references to node IDs or node pools are valid
func (v *HostVolume) validateVolumeForState(vol *structs.HostVolume, snap *state.StateSnapshot) error {
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 nilView on GitHub (pinned to 482b49bf1a)
Solutions
- Get the current node ID via `nomad node status -verbose` and update the spec.
- Re-register/rejoin the node if it should exist but was deregistered.
- Use client name-based selection where supported instead of a hard-coded ID.
- Fix copy/paste errors where the ID came from another cluster.
Example fix
// before
node_id = "9f8e7d6c-OLD"
// after
node_id = "$(nomad node status -verbose | awk '/<client-name>/{print $1}')" Defensive patterns
Strategy: validation
Validate before calling
nodes, _, _ := client.Nodes().List(nil)
found := false
for _, n := range nodes {
if n.ID == vol.NodeID { found = true }
}
if !found { return fmt.Errorf("node %q not in cluster", vol.NodeID) } Type guard
func nodeExists(id string, nodes []*api.NodeListStub) bool {
for _, n := range nodes { if n.ID == id { return true } }
return false
} Try / catch
if strings.Contains(err.Error(), "does not exist") && strings.Contains(err.Error(), "node") {
// refresh node ID from `nomad node status` and resubmit
} Prevention
- Resolve node IDs dynamically from the node list
- Re-generate specs after node reinstall/drain
- Prefer client-name or pool selection over raw UUIDs
- Never copy node IDs across clusters
When it happens
Trigger: Submitting a host volume with vol.NodeID set to an ID absent from `nomad node status` — e.g. typo'd UUID, node deregistered after draining, or ID from another cluster/region.
Common situations: Nodes reinstalled (new node ID) while volume specs keep old IDs; cluster rebuilds; script-generated specs with truncated node IDs; cross-region spec reuse.
Related errors
- No node(s) with prefix or id %q found
- Unknown node %q
- cannot update volume %q: volume does not exist
- node pool %q does not exist
- no such volume: %s
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/cbf2b204a2992484.
Report an issue: GitHub.