hashicorp/nomad · error

structs.ErrUnknownAllocationPrefix

Error message

structs.ErrUnknownAllocationPrefix

What it means

When a CSI volume claim with state 'taken' references an allocation, the state store looks it up with allocByIDImpl inside the same transaction. If that lookup returns a database error (not merely nil), the store wraps the shared sentinel structs.ErrUnknownAllocationPrefix and aborts the claim. It means the allocation the claim depends on could not be read from state.

Source

Thrown at nomad/state/state_store.go:2892

	row, err := txn.First(TableCSIVolumes, "id", namespace, id)
	if err != nil {
		return fmt.Errorf("volume lookup failed: %s: %v", id, err)
	}
	if row == nil {
		return fmt.Errorf("volume not found: %s", id)
	}

	orig, ok := row.(*structs.CSIVolume)
	if !ok {
		return fmt.Errorf("volume row conversion error")
	}

	var alloc *structs.Allocation
	if claim.State == structs.CSIVolumeClaimStateTaken {
		alloc, err = s.allocByIDImpl(txn, nil, claim.AllocationID)
		if err != nil {
			s.logger.Error("AllocByID failed", "error", err)
			return fmt.Errorf(structs.ErrUnknownAllocationPrefix)
		}
		if alloc == nil {
			s.logger.Error("AllocByID failed to find alloc", "alloc_id", claim.AllocationID)
		}
	}

	volume, err := s.csiVolumeDenormalizePluginsTxn(txn, orig.Copy())
	if err != nil {
		return err
	}
	volume, err = s.csiVolumeDenormalizeTxn(txn, nil, volume)
	if err != nil {
		return err
	}

	// In the case of a job deregistration, there will be no allocation ID
	// for the claim but we still want to write an updated index to the volume
	// so that volume reaping is triggered

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Check server logs for the accompanying 'AllocByID failed' error with the underlying cause
  2. Verify disk health and free space on the server data_dir (BoltDB errors are common when disk is full)
  3. Restart the Nomad server and, if state is persistently corrupt, restore from a known-good raft snapshot
  4. Re-run the job/alloc so a fresh claim is created against an existing allocation
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify the allocation exists before issuing a claim
alloc, _, err := client.Allocations().Info(claim.AllocationID, nil)
if err != nil || alloc == nil {
	return fmt.Errorf("alloc %s not found; cannot claim volume", claim.AllocationID)
}

Type guard

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

Try / catch

err := client.CSIVolumes().Claim(claim)
if err != nil && strings.Contains(err.Error(), structs.ErrUnknownAllocationPrefix) {
	// alloc lookup failed: re-resolve alloc or re-run job
}

Prevention

When it happens

Trigger: CSIVolumeClaim with claim.State == CSIVolumeClaimStateTaken and a non-empty AllocationID while the alloc table lookup fails — e.g. memdb I/O error, transaction corruption, or a Raft entry applied against inconsistent state.

Common situations: Corrupted Nomad server state; claims replayed from raft logs after a partial snapshot restore; storage backend (BoltDB) issues on disk-full conditions.

Related errors


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