docker/cli · error
invalid field ' ' must be a key=value pair
Error message
invalid field '%s' must be a key=value pair
What it means
Returned by MountOpt.Set (opts/mount.go:63) for a comma-separated mount field that has no '=' and is not one of the recognized bare-boolean toggles (readonly, ro, volume-nocopy, bind-nonrecursive, bind-create-src). Every non-boolean option must be expressed as key=value; a bare word that isn't whitelisted is treated as a malformed field.
Solutions
- Convert the field to key=value, e.g. source=/data.
- If you meant a boolean toggle, use the exact spelling: readonly, ro, volume-nocopy, bind-nonrecursive, or bind-create-src.
- Check the field name spelling against the supported options list.
Example fix
// before --mount "type=bind,source,target=/data,readonly" // after --mount "type=bind,source=/data,target=/data,readonly"
Defensive patterns
Strategy: validation
Validate before calling
var mountBoolToggles = map[string]bool{"readonly": true, "ro": true, "volume-nocopy": true, "bind-nonrecursive": true, "bind-create-src": true}
// validateBareFields checks that any '='-less field is a known boolean toggle.
func validateBareFields(spec string) error {
r := csv.NewReader(strings.NewReader(spec))
fields, err := r.Read()
if err != nil {
return err
}
for _, f := range fields {
if !strings.Contains(f, "=") && !mountBoolToggles[strings.ToLower(f)] {
return fmt.Errorf("field %q must be key=value or a known boolean toggle", f)
}
}
return nil
} Try / catch
if err := m.Set(spec); err != nil {
return fmt.Errorf("mount %q: %w", spec, err)
} Prevention
- Use key=value for any option that takes a value.
- Keep a list of accepted bare toggles next to your mount builder.
- Lint for typos like read-only in favor of readonly.
When it happens
Trigger: Passing a bare token like `readonly` is fine, but `source`, `target`, `tmpfs-size`, `consistency`, or any value-bearing option written without `=value` triggers this. Also fires for typos of a boolean name (e.g. `read-only`, `readnoly`).
Common situations: Writing `--mount type=volume,source,target=/data` (forgot source value), using a hyphenated variant like `read-only`, or assuming a flag name exists as a bare toggle when it requires a value.
Related errors
- invalid value for ' ': value is empty
- invalid value for ' ' in ' ': value should not have…
- invalid value for ' ': invalid boolean value ( ): must be…
- invalid option ' ' in ' ': option should not have whitespace
- invalid value for : (must be "enabled", "disabled"…
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/d28a304f6c9219cc.
Report an issue: GitHub.
Appendix: source
Thrown at opts/mount.go:63
if hasValue {
v := strings.TrimSpace(val)
if v == "" {
return fmt.Errorf("invalid value for '%s': value is empty", key)
}
if v != val {
return fmt.Errorf("invalid value for '%s' in '%s': value should not have whitespace", key, field)
}
}
// TODO(thaJeztah): these options should not be case-insensitive.
key = strings.ToLower(key)
if !hasValue {
switch key {
case "readonly", "ro", "volume-nocopy", "bind-nonrecursive", "bind-create-src":
// boolean values
default:
return fmt.Errorf("invalid field '%s' must be a key=value pair", field)
}
}
switch key {
case "type":
mount.Type = mounttypes.Type(strings.ToLower(val))
case "source", "src":
mount.Source = val
if !filepath.IsAbs(val) && strings.HasPrefix(val, ".") {
if abs, err := filepath.Abs(val); err == nil {
mount.Source = abs
}
}
case "target", "dst", "destination":
mount.Target = val
case "readonly", "ro":
mount.ReadOnly, err = parseBoolValue(key, val, hasValue)
if err != nil {View on GitHub (pinned to 4f84911bfe)