{"record":{"id":"a1049a9db2979a10","repo":"cilium/cilium","slug":"port-must-be-specified-a1049a","errorCode":null,"errorMessage":"port must be specified","messagePattern":"port must be specified","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/k8s/apis/cilium.io/v2/clrp_types.go","lineNumber":231,"sourceCode":"type CiliumLocalRedirectPolicyList struct {\n\tmetav1.TypeMeta `json:\",inline\"`\n\tmetav1.ListMeta `json:\"metadata\"`\n\n\t// Items is a list of CiliumLocalRedirectPolicy\n\tItems []CiliumLocalRedirectPolicy `json:\"items\"`\n}\n\n// SanitizePortInfo sanitizes all the fields in the PortInfo.\n// It returns port number, name, and protocol derived from the given input  and error (failure cases).\nfunc (pInfo *PortInfo) SanitizePortInfo(checkNamedPort bool) (uint16, string, lb.L4Type, error) {\n\tvar (\n\t\tpInt     uint16\n\t\tpName    string\n\t\tprotocol lb.L4Type\n\t)\n\t// Sanitize port\n\tif pInfo.Port == \"\" {\n\t\treturn pInt, pName, protocol, fmt.Errorf(\"port must be specified\")\n\t} else {\n\t\tp, err := strconv.ParseUint(pInfo.Port, 0, 16)\n\t\tif err != nil {\n\t\t\treturn pInt, pName, protocol, fmt.Errorf(\"unable to parse port: %w\", err)\n\t\t}\n\t\tif p == 0 {\n\t\t\treturn pInt, pName, protocol, fmt.Errorf(\"port cannot be 0\")\n\t\t}\n\t\tpInt = uint16(p)\n\t}\n\t// Sanitize name\n\tif checkNamedPort {\n\t\tif pInfo.Name == \"\" {\n\t\t\treturn pInt, pName, protocol, fmt.Errorf(\"port %s in the local \"+\n\t\t\t\t\"redirect policy spec must have a valid IANA_SVC_NAME, as there are multiple ports\", pInfo.Port)\n\n\t\t}\n\t\tif !iana.IsSvcName(pInfo.Name) {","sourceCodeStart":213,"sourceCodeEnd":249,"githubUrl":"https://github.com/cilium/cilium/blob/ac7b90affa4baf0642e6685319d56907b3a73a6d/pkg/k8s/apis/cilium.io/v2/clrp_types.go#L213-L249","documentation":"SanitizePortInfo in clrp_types.go validates a PortInfo from a CiliumLocalRedirectPolicy spec. If pInfo.Port is the empty string it returns 'port must be specified' because a redirect policy port must carry a numeric port value. The error surfaces when the CRD is processed (policy normalization).","triggerScenarios":"A CiliumLocalRedirectPolicy frontend/backport PortInfo entry has Port: \"\" (only a name, or an empty object) and SanitizePortInfo is invoked on it.","commonSituations":"Users specify only portName or rely on a service name and forget the numeric port field; YAML templating leaves the port empty; copying an example and deleting the port line.","solutions":["Set the port field to a numeric value (e.g. port: 8080) in every port entry of the CLRP spec","Re-apply the policy with kubectl apply after fixing and verify with kubectl get ciliumlocalredirectpolicy -o yaml","If a named port is intended, still provide the numeric port along with the name"],"exampleFix":"// before\nports:\n- name: \"http\"\n// after\nports:\n- name: \"http\"\n  port: 80\n  protocol: TCP","handlingStrategy":"validation","validationCode":"for _, p := range lrp.Spec.RedirectFrontend.Ports {\n    if p.Port == \"\" || p.Port == \"0\" {\n        return fmt.Errorf(\"each CLRP port entry must specify a numeric port\")\n    }\n    n, err := strconv.ParseUint(p.Port, 0, 16)\n    if err != nil || n == 0 { return fmt.Errorf(\"invalid port %q\", p.Port) }\n}","typeGuard":null,"tryCatchPattern":"if err := k8sClient.Create(ctx, lrp); err != nil {\n    if strings.Contains(err.Error(), \"port must be specified\") {\n        // fix spec and re-apply\n    }\n}","preventionTips":["Always set the numeric port in every PortInfo entry","Use kubectl apply --dry-run=server to catch validation before commit","Add CI schema checks for CiliumLocalRedirectPolicy manifests","Never rely on name-only port entries in multi-port policies"],"tags":["kubernetes","validation","port","ciliumlocalredirectpolicy"],"backgroundTag":"missing-port-validation","analyzedSha":"ac7b90affa4baf0642e6685319d56907b3a73a6d","analyzedAt":"2026-08-31T18:27:15.868Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}