{"record":{"id":"05431d8e426c5724","repo":"kubernetes/kops","slug":"failed-to-find-load-balancer-q-public-address","errorCode":null,"errorMessage":"failed to find load-balancer %q public address","messagePattern":"failed to find load-balancer %q public address","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/hetznertasks/loadbalancer.go","lineNumber":90,"sourceCode":"\tif strings.HasPrefix(c.T.ClusterConfigBase.Path(), \"memfs://tests/\") {\n\t\treturn nil, nil\n\t}\n\n\tctx := context.TODO()\n\tcloud := c.T.Cloud.(hetzner.HetznerCloud)\n\tclient := cloud.LoadBalancerClient()\n\n\t// TODO(hakman): Find using label selector\n\tloadbalancers, err := client.All(ctx)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfor _, loadbalancer := range loadbalancers {\n\t\tif loadbalancer.Name == fi.ValueOf(v.Name) {\n\t\t\tvar addresses []string\n\t\t\tif loadbalancer.PublicNet.IPv4.IP == nil {\n\t\t\t\treturn nil, fmt.Errorf(\"failed to find load-balancer %q public address\", fi.ValueOf(v.Name))\n\t\t\t}\n\t\t\taddresses = append(addresses, loadbalancer.PublicNet.IPv4.IP.String())\n\t\t\tfor _, privateNetwork := range loadbalancer.PrivateNet {\n\t\t\t\tif privateNetwork.IP == nil {\n\t\t\t\t\treturn nil, fmt.Errorf(\"failed to find load-balancer %q private address\", fi.ValueOf(v.Name))\n\t\t\t\t}\n\t\t\t\taddresses = append(addresses, privateNetwork.IP.String())\n\t\t\t}\n\t\t\treturn addresses, nil\n\t\t}\n\t}\n\n\treturn nil, nil\n}\n\nfunc (v *LoadBalancer) Find(c *fi.CloudupContext) (*LoadBalancer, error) {\n\tctx := context.TODO()\n\tcloud := c.T.Cloud.(hetzner.HetznerCloud)","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/hetznertasks/loadbalancer.go#L72-L108","documentation":"In the kOps Hetzner load-balancer task's FindAddresses, once the matching hcloud load balancer is found by name, the task requires its public IPv4 address. This error is thrown when the load balancer exists but loadbalancer.PublicNet.IPv4.IP is nil, meaning Hetzner reports no public IPv4 assigned to it.","triggerScenarios":"client.All() returned the load balancer whose name matches the task, but its PublicNet.IPv4.IP is nil — typically because the load balancer was created without a public interface or the public IP allocation has not completed / was disabled.","commonSituations":"Load balancer created manually or by an older tooling version without public IPv4; Hetzner API returns the LB mid-provision before the IP is attached; kOps cluster spec expects a public API endpoint but the LB is private-only.","solutions":["Check the load balancer in the Hetzner console/API and ensure a public IPv4 is assigned to it; recreate the load balancer via kOps if the public interface was disabled.","Wait for/probe the load balancer creation action to finish (WatchProgress) before FindAddresses runs, then re-run kops update/apply.","Align the cluster spec: if the LB is intentionally private-only, configure the kOps API endpoint/Ingress to use the private address path instead of relying on FindAddresses public output."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"lb, _, err := client.Get(ctx, lbName)\nif err != nil {\n    return err\n}\nif lb != nil && lb.PublicNet.IPv4.IP == nil {\n    return fmt.Errorf(\"load balancer %s has no public IPv4 yet; wait for creation to finish\", lbName)\n}","typeGuard":"func hasPublicIPv4(lb *hcloud.LoadBalancer) bool {\n    return lb != nil && lb.PublicNet.IPv4.IP != nil\n}","tryCatchPattern":null,"preventionTips":["Wait for the LB create action (WatchProgress) to complete before querying addresses","Do not disable or remove the public IPv4 on kOps-managed load balancers","Check the Hetzner console that the LB shows a public IP before running kops apply"],"tags":["hetzner","loadbalancer","networking","ipv4"],"backgroundTag":"missing-public-ip","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}