docker/cli · error
bad mode specified
Error message
bad mode specified: %s
What it means
Thrown by validateLinuxPath in the 3-part case when the mode (third segment) fails the validator. validDeviceMode requires each char to be r, w, or m (unique), so any other char or empty string triggers the error.
Solutions
- Use only a combination of r, w, m without duplicates, e.g. rwm, rw, r
- Omit the mode to default to rwm
Example fix
# before docker run --device /dev/x:/dev/y:rwx ... # after docker run --device /dev/x:/dev/y:rwm ...
Defensive patterns
Strategy: validation
Validate before calling
func validDeviceMode(mode string) bool {
seen := map[rune]bool{}
for _, c := range mode {
if c != 'r' && c != 'w' && c != 'm' {
return false
}
if seen[c] {
return false
}
seen[c] = true
}
return len(seen) > 0
} Prevention
- Offer a typed enum for device modes in your wrapper API
When it happens
Trigger: Passing `--device /dev/x:/dev/y:rx` (x invalid), `:rw rw` (space), `:rww` (duplicate), or `:rwx` (x not allowed). Only rwm combinations are legal.
Common situations: Using 'x' for execute; repeating a letter; using uppercase; including spaces; misunderstanding that device mode is r/w/m not Unix file modes.
Related errors
- got a device
- invalid device cgroup format
- other flags may not be combined with --rollback
- duplicate mount target
- specify a Compose file (with --compose-file)
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/f8faeda49fa53b28.
Report an issue: GitHub.
Appendix: source
Thrown at cli/command/container/opts.go:1122
}
switch len(split) {
case 1:
containerPath = split[0]
val = path.Clean(containerPath)
case 2:
if isValid := validator(split[1]); isValid {
containerPath = split[0]
mode = split[1]
val = fmt.Sprintf("%s:%s", path.Clean(containerPath), mode)
} else {
containerPath = split[1]
val = fmt.Sprintf("%s:%s", split[0], path.Clean(containerPath))
}
case 3:
containerPath = split[1]
mode = split[2]
if isValid := validator(split[2]); !isValid {
return val, fmt.Errorf("bad mode specified: %s", mode)
}
val = fmt.Sprintf("%s:%s:%s", split[0], containerPath, mode)
}
if !path.IsAbs(containerPath) {
return val, fmt.Errorf("%s is not an absolute path", containerPath)
}
return val, nil
}
// validateAttach validates that the specified string is a valid attach option.
func validateAttach(val string) (string, error) {
s := strings.ToLower(val)
if slices.Contains([]string{"stdin", "stdout", "stderr"}, s) {
return s, nil
}
return val, errors.New("valid streams are STDIN, STDOUT and STDERR")
}View on GitHub (pinned to 4f84911bfe)