{"record":{"id":"2cf5ac04c86f40db","repo":"hashicorp/nomad","slug":"missing-node-for-client-registration","errorCode":null,"errorMessage":"missing node for client registration","messagePattern":"missing node for client registration","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"nomad/structs/node.go","lineNumber":600,"sourceCode":"// NodeRegisterRequest is used by the Node.Register RPC endpoint to register a\n// node as being a schedulable entity.\ntype NodeRegisterRequest struct {\n\tNode      *Node\n\tNodeEvent *NodeEvent\n\n\t// CreateNodePool is used to indicate that the node's node pool should be\n\t// created along with the node registration if it doesn't exist.\n\tCreateNodePool bool\n\n\tWriteRequest\n}\n\n// Validate checks that the NodeRegisterRequest is valid. Any returned error can\n// be sent back to the client as a response to the RPC call.\nfunc (n *NodeRegisterRequest) Validate() error {\n\n\tif n.Node == nil {\n\t\treturn errors.New(\"missing node for client registration\")\n\t}\n\tif n.Node.ID == \"\" {\n\t\treturn errors.New(\"missing node ID for client registration\")\n\t}\n\tif n.Node.Datacenter == \"\" {\n\t\treturn errors.New(\"missing datacenter for client registration\")\n\t}\n\tif n.Node.Name == \"\" {\n\t\treturn errors.New(\"missing node name for client registration\")\n\t}\n\tif len(n.Node.Attributes) == 0 {\n\t\treturn errors.New(\"missing attributes for client registration\")\n\t}\n\tif n.Node.SecretID == \"\" {\n\t\treturn errors.New(\"missing node secret ID for client registration\")\n\t}\n\tif n.Node.NodePool != \"\" {\n\t\tif err := ValidateNodePoolName(n.Node.NodePool); err != nil {","sourceCodeStart":582,"sourceCodeEnd":618,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/node.go#L582-L618","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Populate the Node field with a fully initialized *structs.Node before calling Validate or the Register RPC.","If the request came from JSON, confirm the payload nests the node object under the correct key (\"Node\") and that unmarshaling succeeded.","Add a pre-flight nil check in the caller and fail fast with a descriptive client-side error."],"exampleFix":"// before\nreq := &structs.NodeRegisterRequest{}\nerr := req.Validate()\n// after\nreq := &structs.NodeRegisterRequest{Node: &structs.Node{ID: nodeID, Datacenter: dc, Name: name}}\nerr := req.Validate()","handlingStrategy":"validation","validationCode":"if req == nil || req.Node == nil {\n\treturn errors.New(\"registration requires a populated Node\")\n}","typeGuard":"func validRegisterRequest(r *structs.NodeRegisterRequest) bool {\n\treturn r != nil && r.Node != nil && r.Node.ID != \"\"\n}","tryCatchPattern":"if err := req.Validate(); err != nil {\n\treturn fmt.Errorf(\"node registration rejected: %w\", err)\n}","preventionTips":["Use constructors/helpers that always set Node.","Check JSON unmarshal errors before using the request.","Add a nil-check unit test for registration payloads."],"tags":["nomad","rpc","validation","nil-pointer"],"backgroundTag":"missing-required-argument","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"}