{"record":{"id":"c587496137e2c9cc","repo":"docker/cli","slug":"invalid-hostport-binding-s-for-port-d","errorCode":null,"errorMessage":"invalid hostport binding (%s) for port (%d)","messagePattern":"invalid hostport binding \\((.+?)\\) for port \\((.+?)\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"opts/swarmopts/port.go","lineNumber":172,"sourceCode":"func (p *PortOpt) Value() []swarm.PortConfig {\n\treturn p.ports\n}\n\n// ConvertPortToPortConfig converts ports to the swarm type\nfunc ConvertPortToPortConfig(\n\tportProto network.Port,\n\tportBindings map[nat.Port][]nat.PortBinding,\n) ([]swarm.PortConfig, error) {\n\tports := make([]swarm.PortConfig, 0, len(portBindings))\n\tfor _, binding := range portBindings[nat.Port(portProto.String())] {\n\t\tif p := net.ParseIP(binding.HostIP); p != nil && !p.IsUnspecified() {\n\t\t\t// TODO(thaJeztah): use context-logger, so that this output can be suppressed (in tests).\n\t\t\tlogrus.Warnf(\"ignoring IP-address (%s:%s) service will listen on '0.0.0.0'\", net.JoinHostPort(binding.HostIP, binding.HostPort), portProto.String())\n\t\t}\n\n\t\tpr, err := network.ParsePortRange(binding.HostPort)\n\t\tif err != nil && binding.HostPort != \"\" {\n\t\t\treturn nil, fmt.Errorf(\"invalid hostport binding (%s) for port (%d)\", binding.HostPort, portProto.Num())\n\t\t}\n\n\t\tfor p := range pr.All() {\n\t\t\tports = append(ports, swarm.PortConfig{\n\t\t\t\t// TODO Name: ?\n\t\t\t\tProtocol:      portProto.Proto(),\n\t\t\t\tTargetPort:    uint32(portProto.Num()),\n\t\t\t\tPublishedPort: uint32(p.Num()),\n\t\t\t\tPublishMode:   swarm.PortConfigPublishModeIngress,\n\t\t\t})\n\t\t}\n\t}\n\treturn ports, nil\n}\n","sourceCodeStart":154,"sourceCodeEnd":187,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/opts/swarmopts/port.go#L154-L187","documentation":"Thrown by ConvertPortToPortConfig (port.go:172) when, in short syntax, the host-port portion of a binding cannot be parsed as a valid port or port range by network.ParsePortRange. Only fired when HostPort is non-empty (empty is allowed at line 171). The host port string must be a single integer or an a-b range.","triggerScenarios":"Passing `--publish abc:80`, `8080-9090-100:80`, `80http:80`, or any short-syntax value whose left-of-colon host part is non-empty and malformed. ParsePortRange returns an error, line 172 wraps it.","commonSituations":"Typos in the published port, accidental inclusion of protocol/units in the host slot, malformed ranges (two dashes), or stray characters from shell expansion.","solutions":["Use a single integer or a clean `low-high` range for the host port: `--publish 8080:80` or `--publish 8080-8082:80`.","Put the protocol after a '/', not in the host slot: `--publish 8080:80/udp`.","Remove letters/extra separators from the host port.","Pre-validate ranges with network.ParsePortRange before passing."],"exampleFix":"// before\n--publish 8080-9090-100:80\n// after\n--publish 8080-9090:80","handlingStrategy":"validation","validationCode":"// Validate the short-syntax host port / range before submission.\nif binding.HostPort != \"\" {\n    if _, err := network.ParsePortRange(binding.HostPort); err != nil {\n        return fmt.Errorf(\"host port %q is not a valid port or range\", binding.HostPort)\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use a single integer or a clean low-high range for the host port.","Put protocol after '/', not in the host slot.","Avoid multiple dashes (low-high only, one separator).","Pre-validate with network.ParsePortRange."],"tags":["docker","swarm","port","validation","networking","port-range","cli"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}