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
- Regenerate the node identity token so it includes a non-empty node_pool claim (upgrade/restart the client on a current Nomad version).
- Verify the client's node is assigned to a node pool; ensure the signing template populates NodePool.
- 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
- Keep clients and servers on versions that mint node-pool identity claims.
- Include node_pool in any custom identity signing templates.
- Rotate node identity tokens after cluster upgrades.
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
- JWT auth method requires either OIDCDiscoveryURL, or JWKS UR
- missing login token
- Invalid node pool name '%s'
- Invalid node pool policy '%s' for '%s'
- Invalid node pool capability '%s' for '%s'
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/d8b56484aba7714b.
Report an issue: GitHub.