{"record":{"id":"4a0a37c91c516636","repo":"docker/cli","slug":"hostip-is-not-supported","errorCode":null,"errorMessage":"hostip is not supported","messagePattern":"hostip is not supported","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"opts/swarmopts/port.go","lineNumber":116,"sourceCode":"\t\t}\n\n\t\tif pConfig.TargetPort == 0 {\n\t\t\treturn fmt.Errorf(\"missing mandatory field '%s'\", portOptTargetPort)\n\t\t}\n\n\t\tp.ports = append(p.ports, pConfig)\n\t} else {\n\t\t// short syntax ([ip:]public:private[/proto])\n\t\t//\n\t\t// TODO(thaJeztah): we need an equivalent that handles the \"ip-address\" part without depending on the nat package.\n\t\tports, portBindingMap, err := nat.ParsePortSpecs([]string{value})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tfor _, portBindings := range portBindingMap {\n\t\t\tfor _, portBinding := range portBindings {\n\t\t\t\tif portBinding.HostIP != \"\" {\n\t\t\t\t\treturn errors.New(\"hostip is not supported\")\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvar portConfigs []swarm.PortConfig\n\t\tfor port := range ports {\n\t\t\tportProto, err := network.ParsePort(string(port))\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tportConfig, err := ConvertPortToPortConfig(portProto, portBindingMap)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tportConfigs = append(portConfigs, portConfig...)\n\t\t}\n\t\tp.ports = append(p.ports, portConfigs...)\n\t}","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/opts/swarmopts/port.go#L98-L134","documentation":"Thrown by PortOpt.Set in the SHORT port syntax path when a parsed port binding carries a non-empty HostIP. Swarm service port configs (--publish in docker service create) do not support binding to a specific host IP; only the long key=value syntax is used for fine control. The error is returned after nat.ParsePortSpecs succeeds but yields a HostIP.","triggerScenarios":"Using the short syntax with an IP prefix, e.g. --publish 127.0.0.1:8080:80, with docker service create/update.","commonSituations":"Copying a docker run -p 127.0.0.1:8080:80 binding verbatim into docker service create, expecting the same behavior. Swarm ingress/host-mode publishing does not pin to a host IP via short syntax.","solutions":["Drop the IP prefix for swarm services: --publish 8080:80.","If host-mode is intended, use the long syntax with mode=host and omit the IP: published=8080,target=80,mode=host.","Use docker run (not swarm) if you truly need host-IP port binding."],"exampleFix":"# before\ndocker service create --publish 127.0.0.1:8080:80 nginx\n# after\ndocker service create --publish 8080:80 nginx","handlingStrategy":"validation","validationCode":"// for swarm service ports, reject short syntax with an IP prefix\nif regexp.MustCompile(`^\\d+\\.\\d+\\.\\d+\\.\\d+:`).MatchString(portSpec) {\n    return errors.New(\"host IP is not supported in short swarm publish syntax\")\n}","typeGuard":null,"tryCatchPattern":"if err := portOpt.Set(spec); err != nil {\n    return err\n}","preventionTips":["Do not copy docker run -p IP:host:container bindings into docker service create.","Use the long publish syntax (published=,target=,mode=) for swarm."],"tags":["swarm","ports","validation","opts"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}