hashicorp/nomad · error

missing NodeID

Error message

missing NodeID

What it means

The GarbageCollectAll RPC on nomad/client_alloc_endpoint.go validates args.NodeID before forwarding the request to the client. This error is returned when the NodeID field of the NodeSpecificRequest is the empty string, meaning the caller never specified which node's allocations to garbage collect. It is a client-side argument validation failure, thrown before any state lookup or RPC forwarding happens.

Source

Thrown at nomad/client_alloc_endpoint.go:66

	if done, err := a.srv.forward("ClientAllocations.GarbageCollectAll", args, args, reply); done {
		return err
	}
	a.srv.MeasureRPCRate("client_allocations", structs.RateMetricWrite, args)
	if authErr != nil {
		return structs.ErrPermissionDenied
	}
	defer metrics.MeasureSince([]string{"nomad", "client_allocations", "garbage_collect_all"}, time.Now())

	// Check node read permissions
	if aclObj, err := a.srv.ResolveACL(args); err != nil {
		return err
	} else if !aclObj.AllowNodeWrite() {
		return structs.ErrPermissionDenied
	}

	// Verify the arguments.
	if args.NodeID == "" {
		return errors.New("missing NodeID")
	}

	// Make sure Node is valid and new enough to support RPC
	snap, err := a.srv.State().Snapshot()
	if err != nil {
		return err
	}

	_, err = getNodeForRpc(snap, args.NodeID)
	if err != nil {
		return err
	}

	// Get the connection to the client
	state, ok := a.srv.getNodeConn(args.NodeID)
	if !ok {
		return findNodeConnAndForward(a.srv, args.NodeID, "ClientAllocations.GarbageCollectAll", args, reply)
	}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Set args.NodeID to the target node's 36-character UUID before invoking GarbageCollectAll.
  2. Resolve the node by name via the Node List API and copy its ID into the request.
  3. Validate NodeID != "" in your calling code before making the RPC.

Example fix

// before
args := structs.NodeSpecificRequest{}
err := client.GarbageCollectAll(args, &structs.GenericResponse{})
// after
args := structs.NodeSpecificRequest{NodeID: node.ID}
err := client.GarbageCollectAll(args, &structs.GenericResponse{})
Defensive patterns

Strategy: validation

Validate before calling

if node == nil || node.ID == "" {
    return fmt.Errorf("cannot GC all allocations: NodeID is empty; resolve node first")
}

Type guard

func hasNodeID(args *structs.NodeSpecificRequest) bool {
    return args != nil && args.NodeID != ""
}

Prevention

When it happens

Trigger: Calling ClientAllocations.GarbageCollectAll with a structs.NodeSpecificRequest whose NodeID field is "" (zero value left unset).

Common situations: Constructing the request struct without setting NodeID; using a node object whose ID field was empty (e.g. node not yet registered, or a zero-valued struct passed in); a wrapper/CLI that fails to resolve a node name to a NodeID.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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