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

  1. Convert the field to key=value, e.g. source=/data.
  2. If you meant a boolean toggle, use the exact spelling: readonly, ro, volume-nocopy, bind-nonrecursive, or bind-create-src.
  3. 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

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


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)