hashicorp/nomad · error

node identity claims missing node pool

Error message

node identity claims missing node pool

What it means

resolveClaims maps node identity claims to a client ACL, but a client ACL is scoped to a node pool. If the JWT's NodeIdentityClaims is nil or its NodePool field is empty, the server cannot determine which pool's client capabilities to grant and fails. This is a claim-content validation error in the node identity token.

Source

Thrown at nomad/auth/auth.go:747

		return fmt.Errorf("allocation does not exist")
	}

	// the claims for terminal allocs are always treated as expired
	if alloc.ClientTerminalStatus() {
		return fmt.Errorf("allocation is terminal")
	}

	return nil
}

func (s *Authenticator) resolveClaims(claims *structs.IdentityClaims) (*acl.ACL, error) {

	// Nomad node identity claims currently map to a client ACL. If we open this
	// up in the future, we will want to modify this section to perform similar
	// work that is done for workload claims.
	if claims.IsNode() {
		if claims.NodeIdentityClaims == nil || claims.NodeIdentityClaims.NodePool == "" {
			return nil, fmt.Errorf("node identity claims missing node pool")
		}
		return acl.NewClientACL(claims.NodeIdentityClaims.NodePool), nil
	}

	policies, err := s.ResolvePoliciesForClaims(claims)
	if err != nil {
		return nil, err
	}

	// Compile and cache the ACL object. For many claims this will result in an
	// ACL object with no policies, which can be efficiently cached.
	aclObj, err := structs.CompileACLObject(s.aclCache, policies)
	if err != nil {
		return nil, err
	}
	return aclObj, nil
}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Regenerate the node identity token so it includes a non-empty node_pool claim (upgrade/restart the client on a current Nomad version).
  2. Verify the client's node is assigned to a node pool; ensure the signing template populates NodePool.
  3. Check server and client versions match a release that includes node-pool identity claims.

Example fix

// before (token payload)
{ "node_id": "abc", ... } // missing node_pool
// after
{ "node_id": "abc", "node_pool": "prod", ... }
Defensive patterns

Strategy: validation

Validate before calling

claims, err := parseJWTUnverified(nodeToken)
if err != nil { return err }
if claims["node_pool"] == "" || claims["node_pool"] == nil {
    return fmt.Errorf("node token lacks node_pool claim; re-mint token")
}

Prevention

When it happens

Trigger: Presenting a node identity JWT (via ResolveACL or TestResolveClaims) that either lacks NodeIdentityClaims entirely or has an empty NodePool claim — typically a token signed by an older Nomad version or built without the node-pool claim.

Common situations: Upgraded cluster where clients still hold identity tokens minted before node-pool claims were added; custom token minters omitting the node_pool claim; misconfigured node identity signing templates.

Related errors


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