hashicorp/nomad · critical

missing node for client registration

Error message

missing node for client registration

What it means

NodeRegisterRequest.Validate returns this error when the Node field of a client registration request is nil. Registering a Nomad client with the server requires a populated Node struct carrying identity, datacenter, and capability information; a nil Node means nothing can be validated or stored.

Source

Thrown at nomad/structs/node.go:600

// NodeRegisterRequest is used by the Node.Register RPC endpoint to register a
// node as being a schedulable entity.
type NodeRegisterRequest struct {
	Node      *Node
	NodeEvent *NodeEvent

	// CreateNodePool is used to indicate that the node's node pool should be
	// created along with the node registration if it doesn't exist.
	CreateNodePool bool

	WriteRequest
}

// Validate checks that the NodeRegisterRequest is valid. Any returned error can
// be sent back to the client as a response to the RPC call.
func (n *NodeRegisterRequest) Validate() error {

	if n.Node == nil {
		return errors.New("missing node for client registration")
	}
	if n.Node.ID == "" {
		return errors.New("missing node ID for client registration")
	}
	if n.Node.Datacenter == "" {
		return errors.New("missing datacenter for client registration")
	}
	if n.Node.Name == "" {
		return errors.New("missing node name for client registration")
	}
	if len(n.Node.Attributes) == 0 {
		return errors.New("missing attributes for client registration")
	}
	if n.Node.SecretID == "" {
		return errors.New("missing node secret ID for client registration")
	}
	if n.Node.NodePool != "" {
		if err := ValidateNodePoolName(n.Node.NodePool); err != nil {

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Populate the Node field with a fully initialized *structs.Node before calling Validate or the Register RPC.
  2. If the request came from JSON, confirm the payload nests the node object under the correct key ("Node") and that unmarshaling succeeded.
  3. Add a pre-flight nil check in the caller and fail fast with a descriptive client-side error.

Example fix

// before
req := &structs.NodeRegisterRequest{}
err := req.Validate()
// after
req := &structs.NodeRegisterRequest{Node: &structs.Node{ID: nodeID, Datacenter: dc, Name: name}}
err := req.Validate()
Defensive patterns

Strategy: validation

Validate before calling

if req == nil || req.Node == nil {
	return errors.New("registration requires a populated Node")
}

Type guard

func validRegisterRequest(r *structs.NodeRegisterRequest) bool {
	return r != nil && r.Node != nil && r.Node.ID != ""
}

Try / catch

if err := req.Validate(); err != nil {
	return fmt.Errorf("node registration rejected: %w", err)
}

Prevention

When it happens

Trigger: Calling the Node.Register RPC with a NodeRegisterRequest whose Node pointer is nil, typically from hand-built requests, test harnesses, or deserialization that failed silently (JSON body missing the "Node" key).

Common situations: Custom provisioning scripts registering clients via the agent HTTP/RPC API with a malformed payload; Go clients constructing NodeRegisterRequest{} without assigning Node; tests stubbing registration requests.

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/2cf5ac04c86f40db. Report an issue: GitHub.