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
- Set args.NodeID to the target node's 36-character UUID before invoking GarbageCollectAll.
- Resolve the node by name via the Node List API and copy its ID into the request.
- 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
- Always construct NodeSpecificRequest with an explicit NodeID from a resolved node object.
- Resolve node names to IDs via the nodes list API before RPC calls.
- Fail fast with your own validation error rather than an empty-ID RPC.
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.