{"record":{"id":"da6afa80e371225c","repo":"hashicorp/nomad","slug":"volume-topology-request-update-was-not-compatible","errorCode":null,"errorMessage":"volume topology request update was not compatible with existing topology","messagePattern":"volume topology request update was not compatible with existing topology","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/csi.go","lineNumber":834,"sourceCode":"\t\t\t\tok = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif ok {\n\t\t\tv.RequestedCapabilities = other.RequestedCapabilities\n\t\t} else {\n\t\t\terrs = multierror.Append(errs, errors.New(\n\t\t\t\t\"volume requested capabilities update was not compatible with existing capability in use\"))\n\t\t}\n\t} else {\n\t\tv.RequestedCapabilities = other.RequestedCapabilities\n\t}\n\n\t// topologies are immutable, so topology request changes must be\n\t// compatible with the existing topology, if any\n\tif len(v.Topologies) > 0 {\n\t\tif !v.RequestedTopologies.Equal(other.RequestedTopologies) {\n\t\t\terrs = multierror.Append(errs, errors.New(\n\t\t\t\t\"volume topology request update was not compatible with existing topology\"))\n\t\t}\n\t}\n\n\t// MountOptions can be updated so long as the volume isn't in use\n\tif v.InUse() {\n\t\tif !v.MountOptions.Equal(other.MountOptions) {\n\t\t\terrs = multierror.Append(errs, errors.New(\n\t\t\t\t\"can not update mount options while volume is in use\"))\n\t\t}\n\t} else {\n\t\tv.MountOptions = other.MountOptions\n\t}\n\n\t// Secrets can be updated freely\n\tv.Secrets = other.Secrets\n\n\t// must be compatible with parameters set by from CreateVolumeResponse","sourceCodeStart":816,"sourceCodeEnd":852,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/csi.go#L816-L852","documentation":"Raised by CSIVolume.Merge (nomad/structs/csi.go:834) when an update changes the requested topologies of a CSI volume that already has resolved topologies. CSI topologies are immutable: once the storage provider reports where the volume lives (zones, racks, regions), the request must remain compatible with it.","triggerScenarios":"Submitting a volume update where `len(v.Topologies) > 0` and `!v.RequestedTopologies.Equal(other.RequestedTopologies)` — i.e. the requested topologies in the update differ from the volume's stored requested topologies.","commonSituations":"Moving a volume spec to a different availability zone/region and re-submitting; adding or removing a topology segment in HCL; infrastructure changes (new zones) leading to regenerated specs with different topology constraints.","solutions":["Keep the requested topologies identical to the originally registered volume when updating","If the topology must change, deregister the volume and register a new one in the target topology","Verify the spec diff before update — only mutable fields (secrets, context, mount options when not in use, compatible capabilities) should differ"],"exampleFix":"// before\ntopology_request {\n  segments { topology = \"rack\", value = \"rack-2\" } # changed from rack-1\n}\n// after\ntopology_request {\n  segments { topology = \"rack\", value = \"rack-1\" } # unchanged, matches existing volume\n}","handlingStrategy":"validation","validationCode":"if len(existing.Topologies) > 0 && !existing.RequestedTopologies.Equal(update.RequestedTopologies) {\n    return errors.New(\"requested topologies are immutable; deregister and create a new volume\")\n}","typeGuard":"func topologiesMutable(existing, update *structs.CSIVolume) bool {\n    return len(existing.Topologies) == 0 || existing.RequestedTopologies.Equal(update.RequestedTopologies)\n}","tryCatchPattern":null,"preventionTips":["Freeze topology_request stanzas once a volume is created; manage topology changes as new volumes","Avoid templating environment-specific values into topology segments used by existing volumes","Diff RequestedTopologies with existing.Topologies before every update submission"],"tags":["csi","nomad","volume","topology","immutable-field"],"backgroundTag":"immutable-field-update-rejected","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}