kubernetes/kops · error
failed to find load-balancer %q public address
Error message
failed to find load-balancer %q public address
What it means
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.
Source
Thrown at upup/pkg/fi/cloudup/hetznertasks/loadbalancer.go:90
if strings.HasPrefix(c.T.ClusterConfigBase.Path(), "memfs://tests/") {
return nil, nil
}
ctx := context.TODO()
cloud := c.T.Cloud.(hetzner.HetznerCloud)
client := cloud.LoadBalancerClient()
// TODO(hakman): Find using label selector
loadbalancers, err := client.All(ctx)
if err != nil {
return nil, err
}
for _, loadbalancer := range loadbalancers {
if loadbalancer.Name == fi.ValueOf(v.Name) {
var addresses []string
if loadbalancer.PublicNet.IPv4.IP == nil {
return nil, fmt.Errorf("failed to find load-balancer %q public address", fi.ValueOf(v.Name))
}
addresses = append(addresses, loadbalancer.PublicNet.IPv4.IP.String())
for _, privateNetwork := range loadbalancer.PrivateNet {
if privateNetwork.IP == nil {
return nil, fmt.Errorf("failed to find load-balancer %q private address", fi.ValueOf(v.Name))
}
addresses = append(addresses, privateNetwork.IP.String())
}
return addresses, nil
}
}
return nil, nil
}
func (v *LoadBalancer) Find(c *fi.CloudupContext) (*LoadBalancer, error) {
ctx := context.TODO()
cloud := c.T.Cloud.(hetzner.HetznerCloud)View on GitHub (pinned to 4c8573c808)
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.
Defensive patterns
Strategy: validation
Validate before calling
lb, _, err := client.Get(ctx, lbName)
if err != nil {
return err
}
if lb != nil && lb.PublicNet.IPv4.IP == nil {
return fmt.Errorf("load balancer %s has no public IPv4 yet; wait for creation to finish", lbName)
} Type guard
func hasPublicIPv4(lb *hcloud.LoadBalancer) bool {
return lb != nil && lb.PublicNet.IPv4.IP != nil
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- failed to find load-balancer %q private address
- failed to find network for loadbalancer %q
- failed to get load balancers matching label selector %q: %w
- cannot determine challenge endpoint for server %d
- failed to convert network ID %q to int: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/05431d8e426c5724.
Report an issue: GitHub.