{"id":"cedf4e10651bed74","repo":"docker/cli","slug":"invalid-key-value-pair-format-in-driver-options","errorCode":null,"errorMessage":"invalid key/value pair format in driver options","messagePattern":"invalid key/value pair format in driver options","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/command/network/connect.go","lineNumber":95,"sourceCode":"\t\t\t\tLinkLocalIPs: toNetipAddrSlice(options.linklocalips),\n\t\t\t},\n\t\t\tLinks:      options.links.GetSlice(),\n\t\t\tAliases:    options.aliases,\n\t\t\tDriverOpts: driverOpts,\n\t\t\tGwPriority: options.gwPriority,\n\t\t},\n\t})\n\treturn err\n}\n\nfunc convertDriverOpt(options []string) (map[string]string, error) {\n\tdriverOpt := make(map[string]string)\n\tfor _, opt := range options {\n\t\tk, v, ok := strings.Cut(opt, \"=\")\n\t\t// TODO(thaJeztah): we should probably not accept whitespace here (both for key and value).\n\t\tk = strings.TrimSpace(k)\n\t\tif !ok || k == \"\" {\n\t\t\treturn nil, errors.New(\"invalid key/value pair format in driver options\")\n\t\t}\n\t\tdriverOpt[k] = strings.TrimSpace(v)\n\t}\n\treturn driverOpt, nil\n}\n\nfunc toNetipAddrSlice(ips []net.IP) []netip.Addr {\n\tif len(ips) == 0 {\n\t\treturn nil\n\t}\n\tnetIPs := make([]netip.Addr, 0, len(ips))\n\tfor _, ip := range ips {\n\t\tnetIPs = append(netIPs, toNetipAddr(ip))\n\t}\n\treturn netIPs\n}\n\nfunc toNetipAddr(ip net.IP) netip.Addr {","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/docker/cli/blob/e9452d6e785f6e365712b9d71bd7517591773c86/cli/command/network/connect.go#L77-L113","documentation":"docker network connect accepts driver-specific options via --driver-opt key=value. convertDriverOpt (cli/command/network/connect.go:88-96) splits each option on the first '=' with strings.Cut; if there is no '=' at all, or the key is empty/whitespace-only after trimming, the pair is malformed and the CLI rejects it before calling the NetworkConnect API. An empty value ('key=') is allowed; a missing or blank key is not.","triggerScenarios":"`docker network connect --driver-opt somekey mynet ctr` (no '='), `--driver-opt \"=value\"` or `--driver-opt \" =value\"` (empty/whitespace key). Any element of the --driver-opt list failing the k,v,ok := strings.Cut(opt, \"=\"); ok && k != \"\" check.","commonSituations":"Typos omitting the '=' (writing --driver-opt macvlan_mode bridge instead of macvlan_mode=bridge); shell quoting/variable expansion producing an empty key (--driver-opt \"$KEY=$VAL\" with unset KEY); passing comma-joined or space-separated options as one malformed argument.","solutions":["Write each option as key=value: docker network connect --driver-opt com.docker.network.endpoint.ifname=eth2 mynet myctr","Repeat the flag for multiple options rather than concatenating them: --driver-opt k1=v1 --driver-opt k2=v2","In scripts, validate that the key variable is non-empty before composing \"$KEY=$VALUE\""],"exampleFix":"# before\ndocker network connect --driver-opt ifname mynet myctr\n# after\ndocker network connect --driver-opt com.docker.network.endpoint.ifname=eth2 mynet myctr","handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":["docker-cli","network","driver-opts","key-value-parsing","validation"],"analyzedSha":"e9452d6e785f6e365712b9d71bd7517591773c86","analyzedAt":"2026-08-01T07:09:22.474Z","schemaVersion":2}