hashicorp/nomad · error

node not found

Error message

node not found

What it means

Inside the shared deregister path, each NodeID is looked up in the state store; if any ID has no corresponding node entry, deregistration aborts with 'node not found'. The node was already removed or the ID never existed.

Source

Thrown at nomad/node_endpoint.go:591

// BatchDeregister. The caller should have already authorized the request.
func (n *Node) deregister(args *structs.NodeBatchDeregisterRequest,
	reply *structs.NodeUpdateResponse,
	raftApplyFn func() (any, uint64, error),
) error {
	// Look for the node
	snap, err := n.srv.fsm.State().Snapshot()
	if err != nil {
		return err
	}

	nodes := make([]*structs.Node, 0, len(args.NodeIDs))
	for _, nodeID := range args.NodeIDs {
		node, err := snap.NodeByID(nil, nodeID)
		if err != nil {
			return err
		}
		if node == nil {
			return fmt.Errorf("node not found")
		}
		nodes = append(nodes, node)
	}

	// Commit this update via Raft
	_, index, err := raftApplyFn()
	if err != nil {
		n.logger.Error("raft message failed", "error", err)
		return err
	}

	for _, node := range nodes {
		nodeID := node.ID

		// Clear the heartbeat timer if any
		n.srv.clearHeartbeatTimer(nodeID)

		// Create the evaluations for this node

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Verify the node exists via the nodes list API and use its exact UUID
  2. Treat 'node not found' as already-deregistered success in idempotent cleanup scripts
  3. Confirm you are querying the correct region/cluster
  4. If the node should exist, check client connectivity — a stale client may have been garbage-collected
Defensive patterns

Strategy: validation

Validate before calling

node, _, err := client.Nodes().Info(nodeID, nil)
if err != nil || node == nil {
    return nil // already gone; skip
}

Type guard

func nodeExists(n *api.Node, err error) bool { return err == nil && n != nil }

Try / catch

err := client.Nodes().Deregister(nodeID, nil)
if err != nil && strings.Contains(err.Error(), "node not found") {
    return nil // idempotent success
}

Prevention

When it happens

Trigger: Deregister/BatchDeregister called for a node ID absent from the snapshot — node previously deregistered, ID typo'd, or server state restored from an older snapshot.

Common situations: Double-execution of cleanup scripts (node already gone); deregistering after a server state restore; wrong cluster/region targeted.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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