hashicorp/nomad · critical

missing node secret ID for client registration

Error message

missing node secret ID for client registration

What it means

NodeRegisterRequest.Validate returns this error when Node.SecretID is empty. The secret ID is the node's per-node auth credential used to authenticate subsequent RPCs; registering without one would create a node that cannot authenticate, so it is mandatory.

Source

Thrown at nomad/structs/node.go:615

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 {
			return fmt.Errorf("invalid node pool: %v", err)
		}
		if n.Node.NodePool == NodePoolAll {
			return fmt.Errorf("node is not allowed to register in node pool %q", NodePoolAll)
		}
	}

	return nil
}

// ShouldGenerateNodeIdentity compliments the functionality within
// AuthenticateNodeIdentityGenerator to determine whether a new node identity
// should be generated within the RPC handler.
func (n *NodeRegisterRequest) ShouldGenerateNodeIdentity(
	authErr error,

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Ensure the client agent generated its node secret (present in data_dir as the secret file); restart the agent to regenerate if missing, then re-register.
  2. When constructing the request in code, generate and assign a secure random SecretID before Validate.
  3. If migrating old tooling, update it to supply SecretID — legacy auth (node ID as secret) is no longer accepted.

Example fix

// before
node := &structs.Node{ID: id, Datacenter: "dc1", Name: name, Attributes: attrs}
// after
node := &structs.Node{ID: id, Datacenter: "dc1", Name: name, Attributes: attrs,
	SecretID: loadedOrGeneratedSecretID}
Defensive patterns

Strategy: validation

Validate before calling

if node.SecretID == "" {
	return errors.New("node SecretID is required; check data_dir secret file")
}

Try / catch

if err := req.Validate(); err != nil {
	if strings.Contains(err.Error(), "missing node secret ID") {
		return fmt.Errorf("regenerate node secret (restart client agent): %w", err)
	}
	return err
}

Prevention

When it happens

Trigger: Calling Node.Register where Node.SecretID is the empty string — e.g. a client agent whose secret file in data_dir was deleted, or hand-built requests that set ID/DC/Name but skipped SecretID.

Common situations: Corrupted or wiped client data_dir losing node_secret_id; registration requests built by scripts/tools predating secret-ID enforcement (older Nomad versions used SecretID nil-able); testing fixtures copying only partial Node structs.

Related errors


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