docker/cli · error

invalid key/value pair format in driver options

Error message

invalid key/value pair format in driver options

What it means

convertDriverOpt() parses each --driver-opt value as key=value via strings.Cut. If the value has no "=" separator, or the key is empty after TrimSpace, the pair is malformed and the whole parse aborts, returning this error before the NetworkConnect API is called.

Solutions

  1. Use key=value format: `--driver-opt key=value`
  2. Quote the pair if the value contains special characters
  3. Verify each --driver-opt contains exactly one = with a non-empty key

Example fix

// before
docker network connect --driver-opt foo mynet myc
// after
docker network connect --driver-opt foo=bar mynet myc
Defensive patterns

Strategy: validation

Validate before calling

for _, opt := range driverOpts {
    k, v, ok := strings.Cut(opt, "=")
    if !ok || strings.TrimSpace(k) == "" {
        return fmt.Errorf("invalid driver-opt %q: expected key=value", opt)
    }
    _ = v
}

Type guard

func isValidDriverOpt(s string) bool {
    k, _, ok := strings.Cut(s, "=")
    return ok && strings.TrimSpace(k) != ""
}

Prevention

When it happens

Trigger: `docker network connect --driver-opt foo mynet myc` (no =), or `--driver-opt =val` (empty key), or a value like `justakey`.

Common situations: Typos; forgetting the = separator; copying syntax from a different tool that uses spaces or colons; trailing flags concatenated incorrectly.

Related errors


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

Appendix: source

Thrown at cli/command/network/connect.go:95

				LinkLocalIPs: toNetipAddrSlice(options.linklocalips),
			},
			Links:      options.links.GetSlice(),
			Aliases:    options.aliases,
			DriverOpts: driverOpts,
			GwPriority: options.gwPriority,
		},
	})
	return err
}

func convertDriverOpt(options []string) (map[string]string, error) {
	driverOpt := make(map[string]string)
	for _, opt := range options {
		k, v, ok := strings.Cut(opt, "=")
		// TODO(thaJeztah): we should probably not accept whitespace here (both for key and value).
		k = strings.TrimSpace(k)
		if !ok || k == "" {
			return nil, errors.New("invalid key/value pair format in driver options")
		}
		driverOpt[k] = strings.TrimSpace(v)
	}
	return driverOpt, nil
}

func toNetipAddrSlice(ips []net.IP) []netip.Addr {
	if len(ips) == 0 {
		return nil
	}
	netIPs := make([]netip.Addr, 0, len(ips))
	for _, ip := range ips {
		netIPs = append(netIPs, toNetipAddr(ip))
	}
	return netIPs
}

func toNetipAddr(ip net.IP) netip.Addr {

View on GitHub (pinned to 4f84911bfe)