hashicorp/nomad · error

claiming volumes: %w

Error message

claiming volumes: %w

What it means

After restoring mounts, the CSI hook's Prerun claims each requested volume via claimVolumes so the allocation holds a claim on the CSI volume. This error wraps failures in acquiring those claims, e.g. the volume doesn't exist, access mode conflicts, or the controller rejects the claim.

Source

Thrown at client/allocrunner/csi_hook.go:131

	// Initially, populate the result map with all of the requests
	for alias, volumeRequest := range tg.Volumes {
		if volumeRequest.Type == structs.VolumeTypeCSI {
			c.volumeResults[alias] = &volumePublishResult{
				request: volumeRequest,
				stub: &state.CSIVolumeStub{
					VolumeID: volumeRequest.VolumeID(c.alloc.Name)},
			}
		}
	}

	err := c.restoreMounts(c.volumeResults)
	if err != nil {
		return fmt.Errorf("restoring mounts: %w", err)
	}

	err = c.claimVolumes(c.volumeResults)
	if err != nil {
		return fmt.Errorf("claiming volumes: %w", err)
	}

	err = c.mountVolumes(c.volumeResults)
	if err != nil {
		return fmt.Errorf("mounting volumes: %w", err)
	}

	// make the mounts available to the taskrunner's volume_hook
	mounts := helper.ConvertMap(c.volumeResults,
		func(result *volumePublishResult) *csimanager.MountInfo {
			return result.stub.MountInfo
		})
	c.hookResources.SetCSIMounts(mounts)

	// persist the published mount info so we can restore on client restarts
	stubs := helper.ConvertMap(c.volumeResults,
		func(result *volumePublishResult) *state.CSIVolumeStub {
			return result.stub

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Run nomad volume status <volume> to confirm the volume exists and check its claims/capabilities
  2. Align the job's volume block (access_mode, attachment_mode, mount_flags) with the plugin's declared capabilities
  3. Free conflicting claims (stop other allocs or nomad volume detach) for single-writer volumes
  4. Ensure the CSI controller plugin is running and reachable, then reschedule the job

Example fix

// before
volume "data" { type = "csi" ... access_mode = "single-node-writer" }  # already claimed elsewhere
// after
$ nomad volume detach data <other-node>
# or change job:
access_mode = "multi-node-multi-writer"  # if plugin supports it
Defensive patterns

Strategy: validation

Validate before calling

const vol = await nomad.get(`volume/csi/${volumeName}`);
const caps = vol.RequestedCapabilities ?? [];
if (!caps.some(c => c.AccessMode === 'single-node-writer'))
  throw new Error(`volume ${volumeName} lacks required access mode`);
if (vol.Claims && vol.Claims.length >= 1 && mode === 'single-node-writer')
  throw new Error('volume already claimed; free the claim first');

Try / catch

try {
  await runJob(job);
} catch (err) {
  if (String(err).includes('claiming volumes')) {
    const claims = await nomad.get(`volume/csi/${volumeName}`);
    for (const c of claims.Claims ?? []) await nomad.volumeDetach(volumeName, c.NodeID);
    await runJob(job); // retry once after clearing claims
  } else throw err;
}

Prevention

When it happens

Trigger: csiHook.Prerun() -> c.claimVolumes(c.volumeResults) returns an error: volume not found/registered, incompatible volume access mode/capabilities with the task's request, or RPC error to the CSI controller plugin.

Common situations: Job references a volume that was deregistered; host_volume/CSI volume requested with capabilities (access mode, fs type, mount flags) the plugin doesn't support; claim count exceeded for a single-node-reader/writer volume; CSI plugin down.

Related errors


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