docker/cli · error

hostip is not supported

Error message

hostip is not supported

What it means

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.

Solutions

  1. Drop the IP prefix for swarm services: --publish 8080:80.
  2. If host-mode is intended, use the long syntax with mode=host and omit the IP: published=8080,target=80,mode=host.
  3. Use docker run (not swarm) if you truly need host-IP port binding.

Example fix

# before
docker service create --publish 127.0.0.1:8080:80 nginx
# after
docker service create --publish 8080:80 nginx
Defensive patterns

Strategy: validation

Validate before calling

// for swarm service ports, reject short syntax with an IP prefix
if regexp.MustCompile(`^\d+\.\d+\.\d+\.\d+:`).MatchString(portSpec) {
    return errors.New("host IP is not supported in short swarm publish syntax")
}

Try / catch

if err := portOpt.Set(spec); err != nil {
    return err
}

Prevention

When it happens

Trigger: Using the short syntax with an IP prefix, e.g. --publish 127.0.0.1:8080:80, with docker service create/update.

Common situations: 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.

Related errors


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

Appendix: source

Thrown at opts/swarmopts/port.go:116

		}

		if pConfig.TargetPort == 0 {
			return fmt.Errorf("missing mandatory field '%s'", portOptTargetPort)
		}

		p.ports = append(p.ports, pConfig)
	} else {
		// short syntax ([ip:]public:private[/proto])
		//
		// TODO(thaJeztah): we need an equivalent that handles the "ip-address" part without depending on the nat package.
		ports, portBindingMap, err := nat.ParsePortSpecs([]string{value})
		if err != nil {
			return err
		}
		for _, portBindings := range portBindingMap {
			for _, portBinding := range portBindings {
				if portBinding.HostIP != "" {
					return errors.New("hostip is not supported")
				}
			}
		}

		var portConfigs []swarm.PortConfig
		for port := range ports {
			portProto, err := network.ParsePort(string(port))
			if err != nil {
				return err
			}
			portConfig, err := ConvertPortToPortConfig(portProto, portBindingMap)
			if err != nil {
				return err
			}
			portConfigs = append(portConfigs, portConfig...)
		}
		p.ports = append(p.ports, portConfigs...)
	}

View on GitHub (pinned to 4f84911bfe)