{"record":{"id":"33d990d353a6c9c8","repo":"docker/cli","slug":"can-only-update-cluster-volumes","errorCode":null,"errorMessage":"can only update cluster volumes","messagePattern":"can only update cluster volumes","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/command/volume/update.go","lineNumber":55,"sourceCode":"\t_ = flags.SetAnnotation(\"availability\", \"swarm\", []string{\"manager\"})\n\n\treturn cmd\n}\n\nfunc runUpdate(ctx context.Context, dockerCli command.Cli, volumeID, availability string, flags *pflag.FlagSet) error {\n\t// TODO(dperny): For this earliest version, the only thing that can be\n\t// updated is Availability, which is necessary because to delete a cluster\n\t// volume, the availability must first be set to \"drain\"\n\n\tapiClient := dockerCli.Client()\n\n\tres, err := apiClient.VolumeInspect(ctx, volumeID, client.VolumeInspectOptions{})\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif res.Volume.ClusterVolume == nil {\n\t\treturn errors.New(\"can only update cluster volumes\")\n\t}\n\n\tif flags.Changed(\"availability\") {\n\t\tres.Volume.ClusterVolume.Spec.Availability = volume.Availability(availability)\n\t}\n\t_, err = apiClient.VolumeUpdate(ctx, res.Volume.ClusterVolume.ID, client.VolumeUpdateOptions{\n\t\tVersion: res.Volume.ClusterVolume.Version,\n\t\tSpec:    &res.Volume.ClusterVolume.Spec,\n\t})\n\treturn err\n}\n","sourceCodeStart":37,"sourceCodeEnd":67,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/cli/command/volume/update.go#L37-L67","documentation":"Returned by runUpdate (volume/update.go:54-56) when 'docker volume update' is run against a volume whose ClusterVolume field is nil, i.e. a normal local volume rather than a Swarm/cluster volume. The update API only mutates cluster-volume properties (currently Availability), so a non-cluster volume is rejected up front after the VolumeInspect call at line 49.","triggerScenarios":"Running 'docker volume update --availability drain <local-volume-name>' where <local-volume-name> was created by 'docker volume create' (not a cluster volume). res.Volume.ClusterVolume is nil for local volumes, triggering the check at line 54.","commonSituations":"Confusing local volumes with Swarm cluster volumes (cluster volumes require Swarm and API 1.42+). Attempting to drain a local volume before deletion - a workflow only valid for cluster volumes (the comment at update.go:43-45 notes drain is needed before cluster-volume deletion).","solutions":["Use 'docker volume update' only on cluster volumes (created with cluster options / on a Swarm manager).","For a local volume you want to remove, just run 'docker volume rm <name>' (no drain step needed).","Verify the volume type with 'docker volume inspect <name>' and check for a non-null ClusterVolume section."],"exampleFix":"# before (local volume)\ndocker volume update --availability drain mydata\ndocker volume rm mydata\n\n# after (local volumes need no drain)\ndocker volume rm mydata","handlingStrategy":"validation","validationCode":"// Before calling 'docker volume update --availability ...', confirm the volume is a cluster volume.\nfunc isClusterVolume(apiClient client.APIClient, ctx context.Context, name string) (bool, error) {\n    res, err := apiClient.VolumeInspect(ctx, name, client.VolumeInspectOptions{})\n    if err != nil {\n        return false, err\n    }\n    return res.Volume.ClusterVolume != nil, nil\n}","typeGuard":"// canUpdateVolume reports whether the volume supports 'docker volume update'.\nfunc canUpdateVolume(v *volume.Volume) bool {\n    return v != nil && v.ClusterVolume != nil\n}","tryCatchPattern":null,"preventionTips":["Gate 'docker volume update' on a prior VolumeInspect that confirms ClusterVolume != nil.","Remember local volumes need no drain step before 'docker volume rm'.","Only attempt cluster-volume workflows on a Swarm manager with API >= 1.42."],"tags":["docker-volume","cluster-volume","swarm","validation"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}