kubernetes/kops · error
failed to delete load balancer %s(%s): %w
Error message
failed to delete load balancer %s(%s): %w
What it means
Wrapped error from deleteLoadBalancer: hcloud LoadBalancerClient.Delete returned an error while kOps removes the cluster's Hetzner load balancer. The API error (auth, conflict, rate limit, not-found) is preserved through %w.
Source
Thrown at pkg/resources/hetzner/resources.go:273
client := c.FirewallClient()
firewall := r.Obj.(*hcloud.Firewall)
_, err := client.Delete(context.TODO(), firewall)
if err != nil {
return fmt.Errorf("failed to delete firewall %s(%s): %w", r.Name, r.ID, err)
}
return nil
}
func deleteLoadBalancer(cloud fi.Cloud, r *resources.Resource) error {
klog.Infof("Deleting LoadBalancer: %s(%s)", r.Name, r.ID)
c := cloud.(hetzner.HetznerCloud)
client := c.LoadBalancerClient()
loadBalancer := r.Obj.(*hcloud.LoadBalancer)
_, err := client.Delete(context.TODO(), loadBalancer)
if err != nil {
return fmt.Errorf("failed to delete load balancer %s(%s): %w", r.Name, r.ID, err)
}
return nil
}
func deleteServer(cloud fi.Cloud, r *resources.Resource) error {
ctx := context.TODO()
klog.Infof("Deleting Server: %s(%s)", r.Name, r.ID)
c := cloud.(hetzner.HetznerCloud)
serverClient := c.ServerClient()
actionClient := c.ActionClient()
server := r.Obj.(*hcloud.Server)
result, _, err := serverClient.DeleteWithResult(ctx, server)
if err != nil {
return fmt.Errorf("failed to delete server %s(%s): %w", r.Name, r.ID, err)View on GitHub (pinned to 4c8573c808)
Solutions
- Delete or detach all load balancer targets in the Hetzner console, then retry the delete.
- Check token validity and permissions (HCLOUD_TOKEN).
- If not-found, the LB is already removed — rerun delete to refresh state.
- Back off and retry if the wrapped error indicates rate limiting.
Defensive patterns
Strategy: retry
Validate before calling
lb, _, err := c.LoadBalancer.Get(ctx, name)
if err != nil { return err }
if lb != nil && len(lb.Targets) > 0 {
return fmt.Errorf("load balancer %s still has %d targets", name, len(lb.Targets))
} Type guard
func isRateLimited(err error) bool {
var hErr hcloud.Error
return errors.As(err, &hErr) && hErr.Code == hcloud.ErrorCodeRateLimitExceeded
} Try / catch
for attempt := 0; attempt < 3; attempt++ {
err := deleteLoadBalancer(...)
if err == nil { return nil }
var hErr hcloud.Error
if errors.As(err, &hErr) && (hErr.Code == hcloud.ErrorCodeNotFound || hErr.Code == hcloud.ErrorCodeRateLimitExceeded) {
time.Sleep(time.Duration(1<<attempt) * time.Second)
continue
}
return err
}
return err Prevention
- Delete kOps-managed Kubernetes services of type LoadBalancer before cluster teardown so the LB controller doesn't recreate targets.
- Never manage the same Hetzner load balancer from both kOps and manual console edits.
- Verify token write scope before starting delete.
- Retry with backoff on rate-limit errors.
When it happens
Trigger: client.Delete(ctx, loadBalancer) fails: load balancer still has targets/services attached, invalid token, rate limiting, or already deleted externally.
Common situations: Servers were deleted out-of-band leaving stale LB targets; LB managed by both kOps and a Kubernetes service controller; expired credentials during long-lived cluster teardown.
Related errors
- failed to delete network %s(%s): %w
- failed to delete firewall %s(%s): %w
- failed to delete server %s(%s): %w
- failed to delete volume %s(%s): %w
- error getting ingress status: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/ffb3431fad18a63d.
Report an issue: GitHub.