hashicorp/nomad · error
volume name cannot be updated
Error message
volume name cannot be updated
What it means
This error comes from CSIVolume.Merge (nomad/structs/csi.go), which is used (e.g. by reconcileVolume) to apply updated volume claims onto an existing CSIVolume. Immutable identity fields of a volume — its Name, ExternalID, PluginID, CloneID — may not change once registered. When a proposed update carries a different, non-empty Name than the existing volume, Merge appends "volume name cannot be updated" to the returned multierror.
Source
Thrown at nomad/structs/csi.go:790
}
return nil
}
// Merge updates the mutable fields of a volume with those from
// another volume. CSIVolume has many user-defined fields which are
// immutable once set, and many fields that are not
// user-settable. Merge will return an error if we try to mutate the
// user-defined immutable fields after they're set, but silently
// ignore fields that are controlled by Nomad.
func (v *CSIVolume) Merge(other *CSIVolume) error {
if other == nil {
return nil
}
var errs *multierror.Error
if v.Name != other.Name && other.Name != "" {
errs = multierror.Append(errs, errors.New("volume name cannot be updated"))
}
if v.ExternalID != other.ExternalID && other.ExternalID != "" {
errs = multierror.Append(errs, errors.New(
"volume external ID cannot be updated"))
}
if v.PluginID != other.PluginID {
errs = multierror.Append(errs, errors.New(
"volume plugin ID cannot be updated"))
}
if v.CloneID != other.CloneID && other.CloneID != "" {
errs = multierror.Append(errs, errors.New(
"volume clone ID cannot be updated"))
}
if v.SnapshotID != other.SnapshotID && other.SnapshotID != "" {
errs = multierror.Append(errs, errors.New(
"volume snapshot ID cannot be updated"))
}
View on GitHub (pinned to 482b49bf1a)
Solutions
- Keep the volume name identical to the existing registration, or deregister the volume (nomad volume deregister) and register it fresh under the new name.
- Use a distinct volume ID for the renamed volume instead of reusing the old ID.
- Diff the existing volume (nomad volume status <id>) against your spec to spot mismatched immutable fields before submitting.
Example fix
// before
volume "old-name" {
type = "csi"
id = "ebs-0" // previously registered as name "ebs-0" too
external_id = "vol-123"
}
// after: either keep the name
csi_volume "ebs-0" { ... }
// or deregister then re-register with the new name
// nomad volume deregister ebs-0
// nomad volume register new.hcl Defensive patterns
Strategy: validation
Validate before calling
existing, _ := client.Volumes().Get(ctx, volID)
if existing != nil && volSpec.Name != existing.Name {
return fmt.Errorf("volume %s: name is immutable; deregister before renaming", volID)
} Try / catch
if err := csiVolume.Merge(update); err != nil {
if strings.Contains(err.Error(), "volume name cannot be updated") {
return fmt.Errorf("keep the volume name or deregister and re-register")
}
return err
} Prevention
- Diff your volume spec against `nomad volume status <id>` before submitting updates.
- Never rename a volume in place; deregister and register a new volume.
- Use unique volume IDs per name to avoid reuse collisions.
When it happens
Trigger: Submitting a volume registration/update for a CSI volume ID whose spec has a different `name` than the previously registered volume (e.g. `nomad volume update`/register path, or a client reconcile of a volume claim where the stored volume's Name differs from the incoming one).
Common situations: Re-registering a volume after renaming it in the jobspec; copying a volume block from another job with a different name but the same volume ID; state drift after restoring volumes from a snapshot/backup.
Related errors
- volume external ID cannot be updated
- volume plugin ID cannot be updated
- CSI.ControllerAttachVolume: VolumeID is required
- CSI.ControllerAttachVolume: ClientCSINodeID is required
- CSI.ControllerDetachVolume: VolumeID is required
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/cd81a8645b7e558d.
Report an issue: GitHub.