{"record":{"id":"fdb79c38009e596f","repo":"docker/cli","slug":"conflicting-options-cannot-specify-both-link-lo","errorCode":null,"errorMessage":"conflicting options: cannot specify both --link-local-ip and per-network link-local IP addresses","messagePattern":"conflicting options: cannot specify both --link-local-ip and per-network link-local IP addresses","errorType":"validation","errorClass":"invalidParameterErr","httpStatus":null,"severity":"error","filePath":"cli/command/container/opts.go","lineNumber":828,"sourceCode":"func applyContainerOptions(n *opts.NetworkAttachmentOpts, copts *containerOptions) error { //nolint:gocyclo\n\t// TODO should we error if _any_ advanced option is used? (i.e. forbid to combine advanced notation with the \"old\" flags (`--network-alias`, `--link`, `--ip`, `--ip6`)?\n\tif len(n.Aliases) > 0 && copts.aliases.Len() > 0 {\n\t\treturn invalidParameter(errors.New(\"conflicting options: cannot specify both --network-alias and per-network alias\"))\n\t}\n\tif len(n.Links) > 0 && copts.links.Len() > 0 {\n\t\treturn invalidParameter(errors.New(\"conflicting options: cannot specify both --link and per-network links\"))\n\t}\n\tif n.IPv4Address.IsValid() && copts.ipv4Address != nil {\n\t\treturn invalidParameter(errors.New(\"conflicting options: cannot specify both --ip and per-network IPv4 address\"))\n\t}\n\tif n.IPv6Address.IsValid() && copts.ipv6Address != nil {\n\t\treturn invalidParameter(errors.New(\"conflicting options: cannot specify both --ip6 and per-network IPv6 address\"))\n\t}\n\tif n.MacAddress != \"\" && copts.macAddress != \"\" {\n\t\treturn invalidParameter(errors.New(\"conflicting options: cannot specify both --mac-address and per-network MAC address\"))\n\t}\n\tif len(n.LinkLocalIPs) > 0 && copts.linkLocalIPs.Len() > 0 {\n\t\treturn invalidParameter(errors.New(\"conflicting options: cannot specify both --link-local-ip and per-network link-local IP addresses\"))\n\t}\n\tif copts.aliases.Len() > 0 {\n\t\tn.Aliases = make([]string, copts.aliases.Len())\n\t\tcopy(n.Aliases, copts.aliases.GetSlice())\n\t}\n\t// For a user-defined network, \"--link\" is an endpoint option, it creates an alias. But,\n\t// for the default bridge it defines a legacy-link.\n\tif container.NetworkMode(n.Target).IsUserDefined() && copts.links.Len() > 0 {\n\t\tn.Links = make([]string, copts.links.Len())\n\t\tcopy(n.Links, copts.links.GetSlice())\n\t}\n\tif copts.ipv4Address != nil {\n\t\tif ipv4, ok := netip.AddrFromSlice(copts.ipv4Address.To4()); ok {\n\t\t\tn.IPv4Address = ipv4\n\t\t}\n\t}\n\tif copts.ipv6Address != nil {\n\t\tif ipv6, ok := netip.AddrFromSlice(copts.ipv6Address.To16()); ok {","sourceCodeStart":810,"sourceCodeEnd":846,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/cli/command/container/opts.go#L810-L846","documentation":"Thrown by applyContainerOptions when a container is created/run with both the global --link-local-ip flag (which sets copts.linkLocalIPs) and per-network link-local IP addresses embedded inside the --network advanced notation (n.LinkLocalIPs). Docker forbids mixing the legacy global flag style with the newer per-network endpoint notation for the same property, because it cannot decide which one wins for which network. The check is one of a family of mutually-exclusive option guards around lines 812-829.","triggerScenarios":"Run/create a container passing both forms: e.g. `docker run --link-local-ip 169.254.10.10 --network mynet:link_local_ip=169.254.10.11 ...`. The guard at opts.go:827 fires because len(n.LinkLocalIPs)>0 (from the advanced notation) AND copts.linkLocalIPs.Len()>0 (from the global flag).","commonSituations":"Migrating an old script that used --link-local-ip to the advanced --network=name:link_local_ip=... syntax and forgetting to strip the old flag. Copy-pasting compose snippets that mix notations. Templating tools (Helm/Terraform) concatenating flags from multiple sources.","solutions":["Pick ONE notation: use either the global --link-local-ip flag OR the per-network link_local_ip=... inside the --network argument, never both.","If you need different link-local IPs per network, use the advanced per-network notation exclusively and drop --link-local-ip.","Audit your command/docker-compose for both 'link-local-ip' keys appearing in both the top-level and the networks.* section."],"exampleFix":"// before\ndocker run --network mynet:link_local_ip=169.254.10.11 --link-local-ip 169.254.10.10 alpine\n\n// after\ndocker run --network mynet:link_local_ip=169.254.10.11 alpine","handlingStrategy":"validation","validationCode":"// Before building the run args, ensure link-local IPs are set via exactly one path.\n// allowedNotation: \"flag\" (global --link-local-ip) or \"per-network\" (--network name:link_local_ip=...)\nfunc validateLinkLocalIPNotation(globalLinkLocalIPs []string, perNetworkLinkLocalIPs map[string][]string) error {\n    if len(globalLinkLocalIPs) > 0 {\n        for _, ips := range perNetworkLinkLocalIPs {\n            if len(ips) > 0 {\n                return errors.New(\"conflicting options: cannot specify both --link-local-ip and per-network link-local IP addresses\")\n            }\n        }\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Standardize on the advanced --network=name:link_local_ip=... notation in all new code and drop global --link-local-ip.","When refactoring flag builders, grep for both 'link-local-ip' and 'link_local_ip' to catch mixed usage.","In templates, make the link-local IP source a single parameter rather than allowing both paths."],"tags":["network","cli-options","conflicting-flags","container"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}