{"record":{"id":"e714f559c0dce8aa","repo":"kubernetes/kops","slug":"load-balancer-s-d-is-not-public","errorCode":null,"errorMessage":"load balancer %s(%d) is not public","messagePattern":"load balancer (.+?)\\((.+?)\\) is not public","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/hetzner/cloud.go","lineNumber":448,"sourceCode":"// FindClusterStatus was used before etcd-manager to check the etcd cluster status and prevent unsupported changes.\nfunc (c *hetznerCloudImplementation) FindClusterStatus(cluster *kops.Cluster) (*kops.ClusterStatus, error) {\n\treturn nil, nil\n}\n\nfunc (c *hetznerCloudImplementation) GetApiIngressStatus(cluster *kops.Cluster) ([]fi.ApiIngressStatus, error) {\n\tlbName := \"api.\" + cluster.Name\n\n\tclient := c.LoadBalancerClient()\n\tlb, _, err := client.GetByName(context.TODO(), lbName)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get info for load balancer %q: %w\", lbName, err)\n\t}\n\tif lb == nil {\n\t\treturn nil, nil\n\t}\n\n\tif !lb.PublicNet.Enabled {\n\t\treturn nil, fmt.Errorf(\"load balancer %s(%d) is not public\", lb.Name, lb.ID)\n\t}\n\n\tingresses := []fi.ApiIngressStatus{\n\t\t{\n\t\t\tIP: lb.PublicNet.IPv4.IP.String(),\n\t\t},\n\t}\n\n\treturn ingresses, nil\n}\n","sourceCodeStart":430,"sourceCodeEnd":459,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/hetzner/cloud.go#L430-L459","documentation":"GetApiIngressStatus requires the API load balancer to have a public network interface so it can return a public ingress IP. If lb.PublicNet.Enabled is false, it refuses with this error because a private-only LB cannot serve the Kubernetes API endpoint.","triggerScenarios":"The Hetzner load balancer named \"api.<cluster>\" exists but was created/modified with PublicNet disabled (e.g. private-only setup or manual LB edit).","commonSituations":"Someone toggled the LB to private-only in the Hetzner console; a cluster spec change removed the public IP expectation but the kOps code still requires it; importing an existing manually created private LB.","solutions":["Enable the public network on the load balancer in the Hetzner Cloud console (or via API).","Run `kops update cluster --yes` to let kOps recreate the LB per spec.","Verify the cluster spec's API load balancer configuration matches a public LB (`kops edit cluster`).","If a fully private control plane is intended, this code path does not support it; use a different API access mechanism."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"lbs, _, _ := client.LoadBalancer.List(ctx, hcloud.LoadBalancerListOpts{Name: lbName})\nfor _, lb := range lbs {\n  if !lb.PublicNet.Enabled { return fmt.Errorf(\"LB %s must have public net enabled\", lb.Name) }\n}","typeGuard":"func lbIsPublic(lb *hcloud.LoadBalancer) bool { return lb != nil && lb.PublicNet.Enabled }","tryCatchPattern":null,"preventionTips":["Never disable PublicNet on the kOps API load balancer in the Hetzner console.","Keep LB configuration managed by `kops update cluster`.","Audit LB settings after manual console changes."],"tags":["hetzner","load-balancer","configuration"],"backgroundTag":"load-balancer-not-public","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}