hashicorp/nomad · error
unable to update volume: %s
Error message
unable to update volume: %s
What it means
When registering a volume that already exists, Register copies the existing volume and calls reconcileVolume to merge mutable fields. If reconciliation fails (e.g. immutable fields changed like plugin ID, provider, or topology conflict), the update is aborted with this wrapped error.
Source
Thrown at nomad/csi_endpoint.go:348
plugin, err := v.pluginValidateVolume(vol)
if err != nil {
return err
}
// CSIVolume has many user-defined fields which are immutable
// once set, and many fields that are controlled by Nomad and
// are not user-settable. We merge onto a copy of the existing
// volume to allow a user to submit a volume spec for `volume
// create` and reuse it for updates in `volume register`
// without having to manually remove the fields unused by
// register (and similar use cases with API consumers such as
// Terraform).
if existingVol != nil {
existingVol = existingVol.Copy()
// reconcile mutable fields
if err = v.reconcileVolume(plugin, existingVol, vol); err != nil {
return fmt.Errorf("unable to update volume: %s", err)
}
*vol = *existingVol
} else if len(vol.Topologies) == 0 {
// The topologies for the volume have already been set
// when it was created, so for newly register volumes
// we accept the user's description of that topology
if vol.RequestedTopologies != nil {
vol.Topologies = vol.RequestedTopologies.Required
}
}
if err := v.controllerValidateVolume(args, vol, plugin); err != nil {
return err
}
warn, err := v.enforceEnterprisePolicy(snap, vol, existingVol, args.GetIdentity().GetACLToken(), args.PolicyOverride)View on GitHub (pinned to 482b49bf1a)
Solutions
- Read the wrapped cause (%s) to see which field failed reconciliation and revert that field in the spec
- Deregister and re-register the volume if a truly incompatible change is intended
- Keep immutable fields (plugin_id, external ID, topology) unchanged in updated specs
Example fix
// before plugin_id = "new-plugin" // conflicts with existing volume // after plugin_id = "original-plugin" // matches existing volume
Defensive patterns
Strategy: try-catch
Validate before calling
// diff spec against existing volume before re-registering existing, _ := client.CSIVolumes().Get(volID, nil) // ensure immutable fields (plugin_id, external ID) match spec
Try / catch
if err := register(); err != nil && strings.Contains(err.Error(), "unable to update volume") {
var cause = errors.Unwrap(err) // inspect reconcile failure
} Prevention
- Keep immutable volume fields stable across spec updates
- Read the wrapped cause to identify the conflicting field
- Deregister/recreate the volume when an incompatible change is truly needed
When it happens
Trigger: Re-registering an existing volume whose new definition conflicts on immutable/mutable reconcile rules handled by reconcileVolume, causing it to return an error.
Common situations: Changing plugin_id or external ID of an existing volume; editing a spec and re-running nomad volume register; infrastructure drift between spec and stored volume.
Related errors
- missing secret ID
- CSI.ControllerValidateVolume: VolumeID is required
- CSI.ControllerValidateVolume: PluginID is required
- CSI.ControllerAttachVolume: VolumeID is required
- CSI.ControllerAttachVolume: ClientCSINodeID is required
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/05da1c93e101822c.
Report an issue: GitHub.