{"record":{"id":"cbf2b204a2992484","repo":"hashicorp/nomad","slug":"node-q-does-not-exist","errorCode":null,"errorMessage":"node %q does not exist","messagePattern":"node %q does not exist","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/host_volume_endpoint.go","lineNumber":457,"sourceCode":"\t\t}\n\t\terr = vol.ValidateUpdate(existing)\n\t\tif err != nil {\n\t\t\treturn existing, fmt.Errorf(\"validating volume %q update failed: %v\", vol.ID, err)\n\t\t}\n\t}\n\treturn existing, nil\n}\n\n// validateVolumeForState ensures that any references to node IDs or node pools are valid\nfunc (v *HostVolume) validateVolumeForState(vol *structs.HostVolume, snap *state.StateSnapshot) error {\n\tvar poolFromExistingNode string\n\tif vol.NodeID != \"\" {\n\t\tnode, err := snap.NodeByID(nil, vol.NodeID)\n\t\tif err != nil {\n\t\t\treturn err // should never hit, bail out\n\t\t}\n\t\tif node == nil {\n\t\t\treturn fmt.Errorf(\"node %q does not exist\", vol.NodeID)\n\t\t}\n\t\tpoolFromExistingNode = node.NodePool\n\t}\n\n\tif vol.NodePool != \"\" {\n\t\tpool, err := snap.NodePoolByName(nil, vol.NodePool)\n\t\tif err != nil {\n\t\t\treturn err // should never hit, bail out\n\t\t}\n\t\tif pool == nil {\n\t\t\treturn fmt.Errorf(\"node pool %q does not exist\", vol.NodePool)\n\t\t}\n\t\tif poolFromExistingNode != \"\" && poolFromExistingNode != pool.Name {\n\t\t\treturn fmt.Errorf(\"node ID %q is not in pool %q\", vol.NodeID, vol.NodePool)\n\t\t}\n\t}\n\n\treturn nil","sourceCodeStart":439,"sourceCodeEnd":475,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/host_volume_endpoint.go#L439-L475","documentation":"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.","triggerScenarios":"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.","commonSituations":"Nodes reinstalled (new node ID) while volume specs keep old IDs; cluster rebuilds; script-generated specs with truncated node IDs; cross-region spec reuse.","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."],"exampleFix":"// before\nnode_id = \"9f8e7d6c-OLD\"\n// after\nnode_id = \"$(nomad node status -verbose | awk '/<client-name>/{print $1}')\"","handlingStrategy":"validation","validationCode":"nodes, _, _ := client.Nodes().List(nil)\nfound := false\nfor _, n := range nodes {\n    if n.ID == vol.NodeID { found = true }\n}\nif !found { return fmt.Errorf(\"node %q not in cluster\", vol.NodeID) }","typeGuard":"func nodeExists(id string, nodes []*api.NodeListStub) bool {\n    for _, n := range nodes { if n.ID == id { return true } }\n    return false\n}","tryCatchPattern":"if strings.Contains(err.Error(), \"does not exist\") && strings.Contains(err.Error(), \"node\") {\n    // refresh node ID from `nomad node status` and resubmit\n}","preventionTips":["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"],"tags":["nomad","host-volumes","node","not-found"],"backgroundTag":"referenced-resource-not-found","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}