{"record":{"id":"067823c2f8f50ac1","repo":"tailscale/tailscale","slug":"port-ranges-for-proxyclass-q-clash-with-existing","errorCode":null,"errorMessage":"port ranges for ProxyClass %q clash with existing ProxyClass %q","messagePattern":"port ranges for ProxyClass %q clash with existing ProxyClass %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"k8s-operator/reconciler/proxyclass/proxyclass.go","lineNumber":448,"sourceCode":"\t\tif !r.IsValid() {\n\t\t\treturn fmt.Errorf(\"port range %q is invalid\", r.String())\n\t\t}\n\t}\n\n\t// TODO(ChaosInTheCRD): if a ProxyClass that made another invalid (due to port range clash) is deleted,\n\t// the invalid ProxyClass doesn't get reconciled on, and therefore will not go valid. We should fix this.\n\tproxyClassRanges, err := getPortsForProxyClasses(ctx, c)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to get port ranges for ProxyClasses: %w\", err)\n\t}\n\n\tfor _, r := range portRanges {\n\t\tfor pcName, pcr := range proxyClassRanges {\n\t\t\tif pcName == pc.Name {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif pcr.ClashesWith(r) {\n\t\t\t\treturn fmt.Errorf(\"port ranges for ProxyClass %q clash with existing ProxyClass %q\", pc.Name, pcName)\n\t\t\t}\n\t\t}\n\t}\n\n\tif len(portRanges) == 1 {\n\t\treturn nil\n\t}\n\n\tsort.Slice(portRanges, func(i, j int) bool {\n\t\treturn portRanges[i].Port < portRanges[j].Port\n\t})\n\n\tfor i := 1; i < len(portRanges); i++ {\n\t\tprev := portRanges[i-1]\n\t\tcurr := portRanges[i]\n\t\tif curr.Port <= prev.Port || curr.Port <= prev.EndPort {\n\t\t\treturn fmt.Errorf(\"overlapping ranges: %q and %q\", prev.String(), curr.String())\n\t\t}","sourceCodeStart":430,"sourceCodeEnd":466,"githubUrl":"https://github.com/tailscale/tailscale/blob/6e0912f97994f927632b34ae9e63b53d6516a6ac/k8s-operator/reconciler/proxyclass/proxyclass.go#L430-L466","documentation":"Raised in validateNodePortRanges when one of this ProxyClass's NodePort ranges overlaps a range declared by a different existing ProxyClass. NodePorts are cluster-wide, so two ProxyClasses cannot share them; the spec is rejected as invalid.","triggerScenarios":"Thrown at k8s-operator/reconciler/proxyclass/proxyclass.go:448 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["The ProxyClass port range clashes with an existing ProxyClass; choose a non-overlapping port range."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"6e0912f97994f927632b34ae9e63b53d6516a6ac","analyzedAt":"2026-08-18T08:17:25.280Z","contentChangedAt":"2026-08-18T08:17:25.280Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}