hashicorp/nomad · error

could not place volume %q: %w

Error message

could not place volume %q: %w

What it means

The Create RPC for host volumes validated the requested volume, but the internal placement step (placeHostVolume) failed to allocate a host volume ID / slot in the state snapshot. Nomad wraps the underlying placement error so the operator knows which volume could not be placed. This indicates the RPC got past ACL and validation but failed during state mutation.

Source

Thrown at nomad/host_volume_endpoint.go:253

	}
	existing, err := v.validateVolumeUpdate(vol, snap)
	if err != nil {
		return err
	}

	// set zero values as needed, possibly from existing
	now := time.Now()
	vol.CanonicalizeForCreate(existing, now)

	// make sure any namespaces, nodes, or pools actually exist
	err = v.validateVolumeForState(vol, snap)
	if err != nil {
		return fmt.Errorf("validating volume %q against state failed: %v", vol.Name, err)
	}

	_, err = v.placeHostVolume(snap, vol)
	if err != nil {
		return fmt.Errorf("could not place volume %q: %w", vol.Name, err)
	}

	warn, err := v.enforceEnterprisePolicy(
		snap, vol, args.GetIdentity().GetACLToken(), args.PolicyOverride)
	if warn != nil {
		reply.Warnings = warn.Error()
	}
	if err != nil {
		return err
	}

	// serialize client RPC and raft write per volume ID
	index, err := v.serializeCall(vol.ID, "create", func() (uint64, error) {
		// Attempt to create the volume on the client.
		//
		// NOTE: creating the volume on the client via the plugin can't be made
		// atomic with the registration, and creating the volume provides values
		// we want to write on the Volume in raft anyways.

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Inspect the wrapped %w cause in the error message to see the underlying placement failure.
  2. Retry the create request once leader election / state store health is confirmed.
  3. Verify the server logs around placeHostVolume for the concrete error.
  4. Upgrade Nomad if this reproduces consistently on a known-buggy version.

Example fix

// before
_, err = v.placeHostVolume(snap, vol)
if err != nil {
	return fmt.Errorf("could not place volume %q: %w", vol.Name, err)
}
// after: fix the root cause reported by the wrapped error, e.g. ensure
// the volume name does not collide with an existing volume before retrying
existing, _ := snap.HostVolumeByName(nil, vol.Namespace, vol.Name)
if existing != nil {
	return fmt.Errorf("volume %q already exists; choose a new name", vol.Name)
}
Defensive patterns

Strategy: retry

Validate before calling

snap, _, err := client.State().Snapshot(nil)
if err != nil { return err }
// ensure cluster is stable and the name is free before create

Try / catch

err := api.CreateHostVolume(req)
var he *api.StatusError
if errors.As(err, &he) && strings.Contains(he.Error(), "could not place volume") {
    // inspect wrapped cause, back off, retry once after confirming leadership
}

Prevention

When it happens

Trigger: Calling the HostVolume.Create RPC (e.g. `nomad volume create` for CSI/host volumes or the corresponding API POST /v1/volumes/host) when v.placeHostVolume returns an error, such as a state-store write failure or ID collision.

Common situations: Raft/state store instability, leadership flapping during the request, a collision or constraint failure in placeHostVolume, or submitting a create while the cluster state is inconsistent.

Related errors


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