docker/cli · error

invalid value for ' ': invalid boolean value ( ): must be…

Error message

invalid value for '%s': invalid boolean value (%q): must be one of "true", "1", "false", or "0" (default "true")

What it means

Returned by parseBoolValue (opts/mount_utils.go:85) when a mount boolean option (readonly/ro, volume-nocopy, bind-create-src) is given a value that isn't one of the four accepted literals: true, 1, false, 0. Unlike strconv.ParseBool, this parser does not accept t/f/T/F/yes/no. When the option has no '=' (bare toggle), it defaults to true and never reaches this error.

Solutions

  1. Use one of true, 1, false, 0 (lowercase).
  2. For a plain on-switch, omit the value entirely: readonly (defaults to true).
  3. Normalize booleans in generated mount strings before parsing.

Example fix

// before
--mount "type=bind,source=/d,target=/d,readonly=yes"

// after
--mount "type=bind,source=/d,target=/d,readonly=true"
Defensive patterns

Strategy: validation

Validate before calling

var mountBoolValues = map[string]bool{"true": true, "1": true, "false": true, "0": true}

func validateMountBool(key, val string, hasValue bool) error {
    if !hasValue {
        return nil // defaults to true
    }
    if !mountBoolValues[val] {
        return fmt.Errorf("%s must be true/1/false/0, got %q", key, val)
    }
    return nil
}

Try / catch

if err := m.Set(spec); err != nil {
    return fmt.Errorf("mount %q: %w", spec, err)
}

Prevention

When it happens

Trigger: Passing `readonly=yes`, `readonly=on`, `volume-nocopy=True` (capital T), `ro=enabled`, or any non-canonical boolean spelling in a --mount CSV.

Common situations: Using yes/no or True/False from compose/JSON, or assuming Go's broader ParseBool vocabulary applies.

Related errors


AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07). Data as JSON: /api/errors/4af858c7caa4c1db. Report an issue: GitHub.

Appendix: source

Thrown at opts/mount_utils.go:85

	return nil
}

// parseBoolValue returns the boolean value represented by the string. It returns
// true if no value is set.
//
// It is similar to [strconv.ParseBool], but only accepts 1, true, 0, false.
// Any other value returns an error.
func parseBoolValue(key string, val string, hasValue bool) (bool, error) {
	if !hasValue {
		return true, nil
	}
	switch val {
	case "1", "true":
		return true, nil
	case "0", "false":
		return false, nil
	default:
		return false, fmt.Errorf(`invalid value for '%s': invalid boolean value (%q): must be one of "true", "1", "false", or "0" (default "true")`, key, val)
	}
}

func ensureVolumeOptions(m *mount.Mount) *mount.VolumeOptions {
	if m.VolumeOptions == nil {
		m.VolumeOptions = &mount.VolumeOptions{}
	}
	return m.VolumeOptions
}

func ensureVolumeDriver(m *mount.Mount) *mount.Driver {
	ensureVolumeOptions(m)
	if m.VolumeOptions.DriverConfig == nil {
		m.VolumeOptions.DriverConfig = &mount.Driver{}
	}
	return m.VolumeOptions.DriverConfig
}

View on GitHub (pinned to 4f84911bfe)