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

  1. Use only a combination of r, w, m without duplicates, e.g. rwm, rw, r
  2. 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

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


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)