docker/cli · error

invalid field

Error message

invalid field: %s

What it means

Thrown by PortOpt.Set (port.go:56) when a field in the long-syntax --publish value lacks '=' or has an empty key. Long syntax looks like `published=8080,target=80,protocol=tcp,mode=ingress`; any field not matching key=value (or with an empty key after lowercasing) is rejected.

Solutions

  1. Use consistent long syntax: `--publish published=8080,target=80,protocol=tcp,mode=ingress`.
  2. Or use short syntax throughout: `--publish 8080:80`.
  3. Ensure every field has the form key=value with a non-empty key.
  4. Avoid stray commas that create empty fields.

Example fix

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

Strategy: validation

Validate before calling

// Check each long-syntax --publish field is key=value with a non-empty key.
for _, f := range strings.Split(pubVal, ",") {
    k, _, ok := strings.Cut(strings.ToLower(strings.TrimSpace(f)), "=")
    if !ok || k == "" { return fmt.Errorf("publish field %q must be key=value", f) }
}

Prevention

When it happens

Trigger: Passing `--publish published=8080,target` (no value for target), `--publish 8080:80,mode=ingress` (mixing short and long), or a field like `=tcp`. strings.Cut at line 54 yields ok=false or empty key.

Common situations: Mixing the short `IP:PUBLIC:PRIVATE/proto` form with key=value long form, truncating a field, copy-paste errors, or a missing '=' after a key.

Related errors


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

Appendix: source

Thrown at opts/swarmopts/port.go:56

	if err != nil {
		return err
	}
	if longSyntax {
		csvReader := csv.NewReader(strings.NewReader(value))
		fields, err := csvReader.Read()
		if err != nil {
			return err
		}

		pConfig := swarm.PortConfig{
			Protocol:    network.TCP,
			PublishMode: swarm.PortConfigPublishModeIngress,
		}
		for _, field := range fields {
			// TODO(thaJeztah): these options should not be case-insensitive.
			key, val, ok := strings.Cut(strings.ToLower(field), "=")
			if !ok || key == "" {
				return fmt.Errorf("invalid field: %s", field)
			}
			switch key {
			case portOptProtocol:
				switch proto := network.IPProtocol(val); proto {
				case network.TCP, network.UDP, network.SCTP:
					pConfig.Protocol = proto
				default:
					return fmt.Errorf("invalid protocol value '%s'", val)
				}
			case portOptMode:
				switch swarm.PortConfigPublishMode(val) {
				case swarm.PortConfigPublishModeIngress, swarm.PortConfigPublishModeHost:
					pConfig.PublishMode = swarm.PortConfigPublishMode(val)
				default:
					return fmt.Errorf("invalid publish mode value (%s): must be either '%s' or '%s'", val, swarm.PortConfigPublishModeIngress, swarm.PortConfigPublishModeHost)
				}
			case portOptTargetPort:
				tPort, err := strconv.ParseUint(val, 10, 16)

View on GitHub (pinned to 4f84911bfe)