hashicorp/nomad · error
allocation does not exist
Error message
allocation does not exist
What it means
verifyWorkloadIdentityClaim validates a signed workload identity JWT against the current state snapshot. After verifying the claims' allocation ID exists (and has a job), it rejects the claim with 'allocation does not exist' when the alloc is nil or its Job reference is missing — meaning the token references an allocation the server no longer knows about.
Source
Thrown at nomad/auth/auth.go:729
}
if registration == nil {
return "", structs.ErrPermissionDenied
}
return resolveAuthorizedClientNodePoolByNodeID(snap, aclObj, registration.NodeID)
}
func (s *Authenticator) verifyWorkloadIdentityClaim(claims *structs.IdentityClaims) error {
snap, err := s.getState().Snapshot()
if err != nil {
return err
}
alloc, err := snap.AllocByID(nil, claims.AllocationID)
if err != nil {
return err
}
if alloc == nil || alloc.Job == nil {
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")View on GitHub (pinned to 482b49bf1a)
Solutions
- Confirm the allocation ID in the claims still exists: `nomad alloc status <alloc-id>`
- Obtain a fresh workload identity token from a live allocation instead of reusing the old one
- If the job was deleted but needed, redeploy it so the alloc/job references resolve
- Ensure the token is verified against the correct region/cluster where the allocation ran
Example fix
// before: verifying a stale identity token for a reaped alloc
claims.VerifyClaim(oldToken)
// after: check the alloc first
alloc, _ := client.Allocations().Info(ctx, allocID)
if alloc != nil {
claims.VerifyClaim(freshToken)
} Defensive patterns
Strategy: validation
Validate before calling
alloc, _, err := client.Allocations().Info(ctx, allocID)
if err != nil || alloc == nil || alloc.Job == nil {
return errors.New("allocation gone: obtain a fresh workload identity token")
} Type guard
func allocUsableForClaim(a *api.Allocation) bool {
return a != nil && a.Job != nil && a.ClientStatus != "lost"
} Try / catch
if err != nil && strings.Contains(err.Error(), "allocation does not exist") {
// refresh the identity token from a live allocation
token, err = requestNewWorkloadIdentityToken()
} Prevention
- Always fetch a fresh workload identity token from a live allocation before verifying
- Check `nomad alloc status` after job deletions to confirm allocs are gone
- Verify tokens against the region/cluster where the allocation actually ran
- Handle terminal/reaped allocs explicitly in token-refresh logic
When it happens
Trigger: VerifyClaim is called with a workload identity JWT whose AllocationID does not resolve to a live allocation in the state store, or the alloc exists without an associated job (job purged while alloc row lingers).
Common situations: Job deleted/garbage-collected; alloc already reaped from the state store; client presenting an old identity token after the allocation was removed; wrong cluster/region receiving the token.
Related errors
- no signed workload identity available
- error getting signed identity for task %s: %v
- error getting signed identity for service %s: %v
- allocation is terminal
- Service identity must provide at least one target aud value
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/916c2fb108a03357.
Report an issue: GitHub.