docker/cli · error

missing mandatory field

Error message

missing mandatory field '%s'

What it means

Thrown by PortOpt.Set (port.go:101) when the long-syntax --publish value has no `target` field, leaving TargetPort at its zero value (0). The target/container port is mandatory in long syntax; published, protocol, and mode are optional with defaults.

Solutions

  1. Always include target in long syntax: `--publish published=8080,target=80`.
  2. target is the in-container port the service listens on; it cannot be defaulted.
  3. Use short syntax `--publish 8080:80` if you prefer the compact form (both ports mandatory there too).
  4. Pre-check that the parsed fields contain a 'target' key.

Example fix

// before
--publish published=8080,mode=ingress
// after
--publish published=8080,target=80,mode=ingress
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the long-syntax --publish value contains a target field.
hasTarget := false
for _, f := range strings.Split(pubVal, ",") {
    if k, _, _ := strings.Cut(strings.ToLower(strings.TrimSpace(f)), "="); k == "target" {
        hasTarget = true
    }
}
if !hasTarget { return errors.New("target port is required") }

Prevention

When it happens

Trigger: Passing `--publish published=8080,protocol=tcp` with no `target=`, or any long-syntax string that omits target. After the field loop, pConfig.TargetPort == 0, so line 101 fires.

Common situations: Assuming the container port is inferred from the published port, forgetting the target field, or copy-paste that drops it.

Related errors


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

Appendix: source

Thrown at opts/swarmopts/port.go:101

				pConfig.TargetPort = uint32(tPort)
			case portOptPublishedPort:
				pPort, err := strconv.ParseUint(val, 10, 16)
				if err != nil {
					var numErr *strconv.NumError
					if errors.As(err, &numErr) {
						err = numErr.Err
					}
					return fmt.Errorf("invalid published port (%s): value must be an integer: %w", val, err)
				}

				pConfig.PublishedPort = uint32(pPort)
			default:
				return fmt.Errorf("invalid field key: %s", key)
			}
		}

		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")
				}
			}
		}

View on GitHub (pinned to 4f84911bfe)