kubernetes/kops · error
load balancer %s(%d) is not public
Error message
load balancer %s(%d) is not public
What it means
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.
Source
Thrown at upup/pkg/fi/cloudup/hetzner/cloud.go:448
// FindClusterStatus was used before etcd-manager to check the etcd cluster status and prevent unsupported changes.
func (c *hetznerCloudImplementation) FindClusterStatus(cluster *kops.Cluster) (*kops.ClusterStatus, error) {
return nil, nil
}
func (c *hetznerCloudImplementation) GetApiIngressStatus(cluster *kops.Cluster) ([]fi.ApiIngressStatus, error) {
lbName := "api." + cluster.Name
client := c.LoadBalancerClient()
lb, _, err := client.GetByName(context.TODO(), lbName)
if err != nil {
return nil, fmt.Errorf("failed to get info for load balancer %q: %w", lbName, err)
}
if lb == nil {
return nil, nil
}
if !lb.PublicNet.Enabled {
return nil, fmt.Errorf("load balancer %s(%d) is not public", lb.Name, lb.ID)
}
ingresses := []fi.ApiIngressStatus{
{
IP: lb.PublicNet.IPv4.IP.String(),
},
}
return ingresses, nil
}
View on GitHub (pinned to 4c8573c808)
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.
Defensive patterns
Strategy: validation
Validate before calling
lbs, _, _ := client.LoadBalancer.List(ctx, hcloud.LoadBalancerListOpts{Name: lbName})
for _, lb := range lbs {
if !lb.PublicNet.Enabled { return fmt.Errorf("LB %s must have public net enabled", lb.Name) }
} Type guard
func lbIsPublic(lb *hcloud.LoadBalancer) bool { return lb != nil && lb.PublicNet.Enabled } Prevention
- 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.
When it happens
Trigger: The Hetzner load balancer named "api.<cluster>" exists but was created/modified with PublicNet disabled (e.g. private-only setup or manual LB edit).
Common situations: 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.
Related errors
- unknown load balancer Type: %q
- unhandled LoadBalancer type %q
- unhandled LoadBalancer type %q
- %s is required
- failed to list load balancers: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/e714f559c0dce8aa.
Report an issue: GitHub.