hashicorp/nomad · error

allocation missing: %s

Error message

allocation missing: %s

What it means

This error is returned by CSIVolume.claimRead when a read claim references an AllocationID that has no corresponding Allocation object. Nomad requires the actual Allocation to validate the claim against volume scheduling state (ReadAllocs, ReadSchedulable), so a missing allocation aborts the claim. It indicates the claim's allocID does not exist in the state store snapshot being used.

Source

Thrown at nomad/structs/csi.go:625

	if claim.State == CSIVolumeClaimStateTaken {
		switch claim.Mode {
		case CSIVolumeClaimRead:
			return v.claimRead(claim, alloc)
		case CSIVolumeClaimWrite:
			return v.claimWrite(claim, alloc)
		}
	}
	// either GC or a Unpublish checkpoint
	return v.claimRelease(claim)
}

// claimRead marks an allocation as using a volume read-only
func (v *CSIVolume) claimRead(claim *CSIVolumeClaim, alloc *Allocation) error {
	if _, ok := v.ReadAllocs[claim.AllocationID]; ok {
		return nil
	}
	if alloc == nil {
		return fmt.Errorf("allocation missing: %s", claim.AllocationID)
	}

	if !v.ReadSchedulable() {
		return ErrCSIVolumeUnschedulable
	}

	if !v.HasFreeReadClaims() {
		return ErrCSIVolumeMaxClaims
	}

	// Allocations are copy on write, so we want to keep the id but don't need the
	// pointer. We'll get it from the db in denormalize.
	v.ReadAllocs[claim.AllocationID] = nil
	delete(v.WriteAllocs, claim.AllocationID)

	v.ReadClaims[claim.AllocationID] = claim
	delete(v.WriteClaims, claim.AllocationID)
	delete(v.PastClaims, claim.AllocationID)

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Re-submit the volume claim with a valid, currently-running allocation ID (nomad alloc status <id> to confirm it exists).
  2. If the alloc was legitimately stopped, stop or delete the stale claim (nomad volume detach <vol> <allocID>) and re-claim from a live alloc.
  3. Check for a race between claim and job stop; retry the claim after the evaluation completes so the alloc snapshot is consistent.
  4. Verify the state store is intact (nomad operator raft list-peers / snapshot restore) if many allocs are missing.

Example fix

// before
claim := &structs.CSIVolumeClaim{AllocationID: "e62b3c58-4fae-4c1d-8873-bb03a30a4d32"} // alloc already stopped
vol.Claim(structs.CSIVolumeClaimWrite, claim, nil)
// after
alloc, err := state.AllocByID(nil, claimID)
if err != nil || alloc == nil {
    return fmt.Errorf("alloc %s no longer exists; pick a running alloc", claimID)
}
claim := &structs.CSIVolumeClaim{AllocationID: claimID}
vol.Claim(structs.CSIVolumeClaimWrite, claim, alloc)
Defensive patterns

Strategy: validation

Validate before calling

alloc, err := state.AllocByID(nil, claim.AllocationID)
if err != nil {
    return err
}
if alloc == nil {
    return fmt.Errorf("alloc %s does not exist; cannot claim volume %s", claim.AllocationID, vol.ID)
}
err = vol.Claim(structs.CSIVolumeClaimRead, claim, alloc)

Type guard

func allocExists(alloc *structs.Allocation) bool { return alloc != nil && alloc.ID != "" }

Try / catch

err := vol.Claim(structs.CSIVolumeClaimRead, claim, alloc)
if err != nil {
    if strings.Contains(err.Error(), "allocation missing") {
        // alloc was GC'd; drop the stale claim and re-claim from a live alloc
        return retryWithLiveAlloc(claim.VolumeID, jobID)
    }
    return err
}

Prevention

When it happens

Trigger: Calling CSIVolume.Claim (via volume claim RPC) with a CSIVolumeClaim whose AllocationID was deleted (alloc garbage-collected, node lost, job stopped) before the claim is processed, or passing an alloc ID that never existed / was typographically wrong.

Common situations: A volume claim races with allocation deregistration (e.g. job stopped while claim evaluation in flight); state store restored from a backup where the alloc was pruned; a client or tooling submitting a claim with a mistyped alloc ID.

Related errors


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