{"record":{"id":"1d51844427403302","repo":"docker/cli","slug":"missing-mandatory-field-s","errorCode":null,"errorMessage":"missing mandatory field '%s'","messagePattern":"missing mandatory field '(.+?)'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"opts/swarmopts/port.go","lineNumber":101,"sourceCode":"\t\t\t\tpConfig.TargetPort = uint32(tPort)\n\t\t\tcase portOptPublishedPort:\n\t\t\t\tpPort, err := strconv.ParseUint(val, 10, 16)\n\t\t\t\tif err != nil {\n\t\t\t\t\tvar numErr *strconv.NumError\n\t\t\t\t\tif errors.As(err, &numErr) {\n\t\t\t\t\t\terr = numErr.Err\n\t\t\t\t\t}\n\t\t\t\t\treturn fmt.Errorf(\"invalid published port (%s): value must be an integer: %w\", val, err)\n\t\t\t\t}\n\n\t\t\t\tpConfig.PublishedPort = uint32(pPort)\n\t\t\tdefault:\n\t\t\t\treturn fmt.Errorf(\"invalid field key: %s\", key)\n\t\t\t}\n\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}","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/opts/swarmopts/port.go#L83-L119","documentation":"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.","triggerScenarios":"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.","commonSituations":"Assuming the container port is inferred from the published port, forgetting the target field, or copy-paste that drops it.","solutions":["Always include target in long syntax: `--publish published=8080,target=80`.","target is the in-container port the service listens on; it cannot be defaulted.","Use short syntax `--publish 8080:80` if you prefer the compact form (both ports mandatory there too).","Pre-check that the parsed fields contain a 'target' key."],"exampleFix":"// before\n--publish published=8080,mode=ingress\n// after\n--publish published=8080,target=80,mode=ingress","handlingStrategy":"validation","validationCode":"// Ensure the long-syntax --publish value contains a target field.\nhasTarget := false\nfor _, f := range strings.Split(pubVal, \",\") {\n    if k, _, _ := strings.Cut(strings.ToLower(strings.TrimSpace(f)), \"=\"); k == \"target\" {\n        hasTarget = true\n    }\n}\nif !hasTarget { return errors.New(\"target port is required\") }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always include target=N in long syntax.","Remember target is the in-container port and is mandatory.","Use short syntax a:b as an alternative (both ports required).","Pre-scan parsed fields for the 'target' key."],"tags":["docker","swarm","port","validation","networking","cli"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}