docker/cli · error
cluster options are incompatible with type bind
Error message
cluster options are incompatible with type bind
What it means
Returned by handleBindToMount (cli/compose/convert/volume.go:135-136). Cluster options are for Swarm cluster volumes; they have no meaning for a host bind mount, so the converter rejects the pairing at cli/compose/convert/volume.go:136. Because ClusterOpts is an empty struct, even `cluster: {}` triggers it.
Solutions
- Remove the `cluster:` key from the bind entry.
- If a Swarm cluster volume was intended, change `type:` to `cluster`, remove `bind:`/`image:`/`tmpfs:` blocks, and ensure a non-empty source.
Example fix
# before
volumes:
- type: bind
source: /host/data
target: /data
cluster: {}
# after
volumes:
- type: bind
source: /host/data
target: /data Defensive patterns
Strategy: validation
Validate before calling
for i, v := range serviceVolumes {
if v.Type == "bind" && v.Cluster != nil {
return fmt.Errorf("service volume[%d] target=%q: type bind must not declare a cluster block", i, v.Target)
}
} Try / catch
mounts, err := convert.Volumes(serviceVolumes, stackVolumes, namespace)
if err != nil && strings.Contains(err.Error(), "cluster options are incompatible with type bind") {
return fmt.Errorf("compose config error: %w (remove the cluster: block from the bind entry)", err)
} Prevention
- Cluster volumes are Swarm-only; do not mix cluster blocks with non-cluster types.
- Avoid YAML anchors that spread a cluster block across entries of other types.
When it happens
Trigger: ServiceVolumeConfig with Type=="bind" and Cluster!=nil passed to convertVolumeToMount().
Common situations: Migrating a cluster volume to a bind without dropping the `cluster:` key; YAML anchors injecting the field.
Related errors
- bind options are incompatible with type cluster
- cluster options are incompatible with type image
- invalid bind source, source cannot be empty
- volume options are incompatible with type bind
- image options are incompatible with type bind
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/06e19999b58a6f18.
Report an issue: GitHub.
Appendix: source
Thrown at cli/compose/convert/volume.go:136
}
func handleBindToMount(volume composetypes.ServiceVolumeConfig) (mount.Mount, error) {
result := createMountFromVolume(volume)
if volume.Source == "" {
return mount.Mount{}, errors.New("invalid bind source, source cannot be empty")
}
if volume.Volume != nil {
return mount.Mount{}, errors.New("volume options are incompatible with type bind")
}
if volume.Image != nil {
return mount.Mount{}, errors.New("image options are incompatible with type bind")
}
if volume.Tmpfs != nil {
return mount.Mount{}, errors.New("tmpfs options are incompatible with type bind")
}
if volume.Cluster != nil {
return mount.Mount{}, errors.New("cluster options are incompatible with type bind")
}
if volume.Bind != nil {
result.BindOptions = &mount.BindOptions{
Propagation: mount.Propagation(volume.Bind.Propagation),
}
}
return result, nil
}
func handleTmpfsToMount(volume composetypes.ServiceVolumeConfig) (mount.Mount, error) {
result := createMountFromVolume(volume)
if volume.Source != "" {
return mount.Mount{}, errors.New("invalid tmpfs source, source must be empty")
}
if volume.Bind != nil {
return mount.Mount{}, errors.New("bind options are incompatible with type tmpfs")
}View on GitHub (pinned to 4f84911bfe)