hashicorp/nomad · error
volume clone ID cannot be updated
Error message
volume clone ID cannot be updated
What it means
This error is produced by CSIVolume.Merge (nomad/structs/csi.go:782) when a `nomad volume update` (or any volume registration merge) tries to change the clone ID of an existing CSI volume. Nomad treats the clone ID (the source volume/snapshot a volume was cloned from) as an immutable user-defined field once the volume has been created. All immutable-field violations are collected into a hashicorp/go-multierror and returned as one 'validation: ...' error.
Source
Thrown at nomad/structs/csi.go:801
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"))
}
// must be compatible with volume_capabilities
if v.AccessMode != CSIVolumeAccessModeUnknown ||
v.AttachmentMode != CSIVolumeAttachmentModeUnknown {
var ok bool
for _, cap := range other.RequestedCapabilities {
if cap.AccessMode == v.AccessMode &&
cap.AttachmentMode == v.AttachmentMode {
ok = true
break
}
}View on GitHub (pinned to 482b49bf1a)
Solutions
- Remove the `clone_id` (or clone/source stanza) from the update spec — an empty CloneID is silently ignored by Merge, so updates pass when the field is omitted
- If a different clone source is truly needed, deregister the volume (and destroy the external volume if desired) and register a new volume with the new clone ID
- Keep the volume spec in version control and ensure the clone ID field never changes between submits
Example fix
// before (update spec)
volume "data" {
clone_id = "abc-123"
}
// after (update spec omits the immutable field)
volume "data" {
# clone_id omitted; only mutable fields (secrets, context, capabilities) updated
} Defensive patterns
Strategy: validation
Validate before calling
// before submitting a volume update
if other.CloneID != "" && existing.CloneID != other.CloneID {
return fmt.Errorf("clone ID %q differs from registered %q; omit it from updates", other.CloneID, existing.CloneID)
} Type guard
func cloneIDMutable(existing, update *structs.CSIVolume) bool {
return update.CloneID == "" || update.CloneID == existing.CloneID
} Prevention
- Never include immutable fields (clone_id, snapshot_id, external_id, parameters) in volume update specs
- Keep volume specs in version control and diff before resubmitting
- Treat 'validation: ...' multierror messages as field-by-field immutability reports
When it happens
Trigger: Calling the CSIVolume.Merge method (via the VolumeUpsert/update RPC path) with `other.CloneID` different from the stored volume's CloneID while `other.CloneID != ""` — i.e. an update spec that sets a non-empty clone ID that differs from the registered volume.
Common situations: Hand-editing or regenerating a volume spec HCL/JSON that originally included a clone source and resubmitting it with a different clone ID; templating the volume spec so the clone ID varies between environments; copy-pasting a spec from a different volume.
Related errors
- volume snapshot ID cannot be updated
- volume requested capabilities update was not compatible with
- volume topology request update was not compatible with exist
- volume parameters cannot be updated
- missing secret ID
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/05d8ecc7c9f2a12f.
Report an issue: GitHub.