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

  1. Confirm the allocation ID in the claims still exists: `nomad alloc status <alloc-id>`
  2. Obtain a fresh workload identity token from a live allocation instead of reusing the old one
  3. If the job was deleted but needed, redeploy it so the alloc/job references resolve
  4. 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

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


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