kubernetes/kops · error

failed to find load-balancer %q private address

Error message

failed to find load-balancer %q private address

What it means

In the same FindAddresses loop, for every private network attachment (loadbalancer.PrivateNet) the task requires a non-nil IP. This error is thrown when the load balancer is attached to a Hetzner network but the API reports nil for the attachment's IP, i.e., the attachment exists without an assigned private address.

Source

Thrown at upup/pkg/fi/cloudup/hetznertasks/loadbalancer.go:95

	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)
	client := cloud.LoadBalancerClient()

	// TODO(hakman): Find using label selector
	loadbalancers, err := client.All(ctx)
	if err != nil {

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Retry kops apply once the network-attach action completes; confirm in the Hetzner console that the LB shows an IP in the attached network.
  2. Detach and re-attach the load balancer to the Hetzner network (hcloud load-balancer detach-network / attach-network) to force a fresh IP assignment.
  3. Verify the subnet in the Hetzner network has free IPs and is not misconfigured (overlapping CIDRs can prevent assignment).
Defensive patterns

Strategy: retry

Validate before calling

lb, _, err := client.Get(ctx, lbName)
if err != nil {
    return err
}
for _, pn := range lb.PrivateNet {
    if pn.IP == nil {
        return fmt.Errorf("network %d attachment on %s has no IP yet; retry after attach completes", pn.Network.ID, lbName)
    }
}

Type guard

func allPrivateIPsAssigned(lb *hcloud.LoadBalancer) bool {
    for _, pn := range lb.PrivateNet {
        if pn.IP == nil { return false }
    }
    return true
}

Try / catch

err := retry.Do(func() error {
    addrs, err := task.FindAddresses(ctx)
    if err != nil && strings.Contains(err.Error(), "private address") {
        return retry.Temporary(err) // IP not yet assigned; back off and retry
    }
    return err
})

Prevention

When it happens

Trigger: The load balancer has an entry in PrivateNet whose IP is nil — the LB was attached to a network but IP assignment failed or is still in progress, or the network was detached/reattached leaving a stale entry.

Common situations: Load balancer network attachment still provisioning during a kops apply; manual hcloud network attach without IP assignment; race where FindAddresses runs immediately after creating/attaching the LB network.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/bf63fd5d37f546da. Report an issue: GitHub.