docker/cli · error
type is required
Error message
type is required
What it means
Returned by validateExclusiveOptions (opts/mount_utils.go:49) when the mount's Type field is an empty string. When using the CLI's MountOpt.Set parser, Type defaults to mounttypes.TypeVolume, so this error only triggers when a mount.Mount struct is constructed directly (e.g., via the Go SDK/API client) without explicitly setting the Type field.
Solutions
- Set the Type field on the mount.Mount struct to one of: mount.TypeBind, mount.TypeVolume, mount.TypeTmpfs, mount.TypeImage, mount.TypeCluster.
- If building mounts from user input, default Type to mount.TypeVolume like the CLI parser does.
Example fix
// before: no type specified
mount := mount.Mount{
Source: "/data",
Target: "/data",
}
// after: set type explicitly
mount := mount.Mount{
Type: mount.TypeBind,
Source: "/data",
Target: "/data",
} Defensive patterns
Strategy: validation
Validate before calling
func validateMountType(m mounttypes.Mount) error {
if m.Type == "" {
return fmt.Errorf("mount type is required (one of: bind, volume, tmpfs, image, cluster)")
}
return nil
}
// Or default to volume like the CLI parser does:
func ensureMountType(m *mounttypes.Mount) {
if m.Type == "" {
m.Type = mounttypes.TypeVolume
}
} Try / catch
if err := validateMountOptions(&m); err != nil {
if err.Error() == "type is required" {
m.Type = mounttypes.TypeVolume // or TypeBind
return validateMountOptions(&m)
}
return err
} Prevention
- Always set the Type field when constructing mount.Mount structs programmatically.
- Default Type to mount.TypeVolume if building mounts from user input, matching the CLI parser behavior.
- Validate mount structs before passing them to the Docker client API.
When it happens
Trigger: validateMountOptions is called on a mount.Mount struct where m.Type is "" (empty string). This occurs in programmatic/SDK usage where a mount is built without setting Type, not through the CLI --mount flag parser which always defaults Type to TypeVolume.
Common situations: Go code using the Docker client SDK to create a container with a HostConfig.Mounts entry that omits the Type field, or deserialized mount JSON lacking a type field.
Related errors
- images options are incompatible with type volume
- tmpfs options are incompatible with type volume
- bind options are incompatible with type volume
- cluster options are incompatible with type volume
- invalid image source, source cannot be empty
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/b03c02ee2994a133.
Report an issue: GitHub.
Appendix: source
Thrown at opts/mount_utils.go:49
// # no error
return errors.New("option 'bind-recursive=readonly' requires 'bind-propagation=rprivate' to be specified in conjunction")
}
}
}
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 nilView on GitHub (pinned to 4f84911bfe)