docker/cli · error
cannot mix 'bind-*' options with mount type
Error message
cannot mix 'bind-*' options with mount type '%s'
What it means
Returned by validateExclusiveOptions (opts/mount_utils.go:53) when a mount's Type is not TypeBind but BindOptions is non-nil. Each mount type owns an exclusive options struct; bind-* options (bind-propagation, bind-recursive, bind-create-src) are only valid for type=bind. The client validates this to produce a friendly error mirroring daemon-side enforcement.
Solutions
- Switch the mount type to bind if you need bind-* options.
- Or remove all bind-* options (bind-propagation, bind-recursive, bind-create-src) when using type=volume/tmpfs/image/cluster.
Example fix
// before --mount "type=volume,source=v,target=/d,bind-propagation=rshared" // after --mount "type=bind,source=/d,target=/d,bind-propagation=rshared"
Defensive patterns
Strategy: validation
Validate before calling
func validateExclusive(m mount.Mount) error {
if m.Type != mount.TypeBind && m.BindOptions != nil {
return fmt.Errorf("bind-* options require type=bind, got %s", m.Type)
}
return nil
} Try / catch
if err := opts.ValidateExclusive(m); err != nil { // if exposed; else call Set and check error
return err
} Prevention
- Only attach BindOptions when Type == TypeBind.
- In a mount builder, reset the options struct when changing type.
- Unit-test that each emitted mount's type matches its options.
When it happens
Trigger: Constructing a mount with type=volume (or tmpfs/image/cluster) while also setting any bind-* option, e.g. `--mount type=volume,source=v,target=/d,bind-propagation=rshared`, or programmatically populating mount.BindOptions on a non-bind Mount.
Common situations: Reusing a mount spec template across types, or a UI/compose generator that always emits bind-propagation.
Related errors
- invalid value for : (must be "enabled", "disabled"…
- cannot mix 'volume-*' options with mount type
- cannot mix 'image-*' options with mount type
- cannot mix 'tmpfs-*' options with mount type
- cannot mix 'cluster-*' options with mount type
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/93272f602c651963.
Report an issue: GitHub.
Appendix: source
Thrown at opts/mount_utils.go:53
}
return nil
}
// validateExclusiveOptions checks if the given mount config only contains
// options for the given mount-type.
//
// This is the client-side equivalent of [mounts.validateExclusiveOptions] in
// the daemon, but with error-messages matching client-side flags / options.
//
// [mounts.validateExclusiveOptions]: https://github.com/moby/moby/blob/v2.0.0-beta.6/daemon/volume/mounts/validate.go#L31-L50
func validateExclusiveOptions(m *mount.Mount) error {
if m.Type == "" {
return errors.New("type is required")
}
if m.Type != mount.TypeBind && m.BindOptions != nil {
return fmt.Errorf("cannot mix 'bind-*' options with mount type '%s'", m.Type)
}
if m.Type != mount.TypeVolume && m.VolumeOptions != nil {
return fmt.Errorf("cannot mix 'volume-*' options with mount type '%s'", m.Type)
}
if m.Type != mount.TypeImage && m.ImageOptions != nil {
return fmt.Errorf("cannot mix 'image-*' options with mount type '%s'", m.Type)
}
if m.Type != mount.TypeTmpfs && m.TmpfsOptions != nil {
return fmt.Errorf("cannot mix 'tmpfs-*' options with mount type '%s'", m.Type)
}
if m.Type != mount.TypeCluster && m.ClusterOptions != nil {
return fmt.Errorf("cannot mix 'cluster-*' options with mount type '%s'", m.Type)
}
return nil
}
// parseBoolValue returns the boolean value represented by the string. It returns
// true if no value is set.View on GitHub (pinned to 4f84911bfe)