docker/cli · error
can only update cluster volumes
Error message
can only update cluster volumes
What it means
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.
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.
Example fix
# before (local volume) docker volume update --availability drain mydata docker volume rm mydata # after (local volumes need no drain) docker volume rm mydata
Defensive patterns
Strategy: validation
Validate before calling
// Before calling 'docker volume update --availability ...', confirm the volume is a cluster volume.
func isClusterVolume(apiClient client.APIClient, ctx context.Context, name string) (bool, error) {
res, err := apiClient.VolumeInspect(ctx, name, client.VolumeInspectOptions{})
if err != nil {
return false, err
}
return res.Volume.ClusterVolume != nil, nil
} Type guard
// canUpdateVolume reports whether the volume supports 'docker volume update'.
func canUpdateVolume(v *volume.Volume) bool {
return v != nil && v.ClusterVolume != nil
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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).
Related errors
- error reading from STDIN: data is empty
- config file is required
- cannot supply extra formatting options to the pretty…
- other flags may not be combined with --rollback
- duplicate mount target
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/33d990d353a6c9c8.
Report an issue: GitHub.
Appendix: source
Thrown at cli/command/volume/update.go:55
_ = flags.SetAnnotation("availability", "swarm", []string{"manager"})
return cmd
}
func runUpdate(ctx context.Context, dockerCli command.Cli, volumeID, availability string, flags *pflag.FlagSet) error {
// TODO(dperny): For this earliest version, the only thing that can be
// updated is Availability, which is necessary because to delete a cluster
// volume, the availability must first be set to "drain"
apiClient := dockerCli.Client()
res, err := apiClient.VolumeInspect(ctx, volumeID, client.VolumeInspectOptions{})
if err != nil {
return err
}
if res.Volume.ClusterVolume == nil {
return errors.New("can only update cluster volumes")
}
if flags.Changed("availability") {
res.Volume.ClusterVolume.Spec.Availability = volume.Availability(availability)
}
_, err = apiClient.VolumeUpdate(ctx, res.Volume.ClusterVolume.ID, client.VolumeUpdateOptions{
Version: res.Volume.ClusterVolume.Version,
Spec: &res.Volume.ClusterVolume.Spec,
})
return err
}
View on GitHub (pinned to 4f84911bfe)