{"record":{"id":"ffb3431fad18a63d","repo":"kubernetes/kops","slug":"failed-to-delete-load-balancer-s-s-w","errorCode":null,"errorMessage":"failed to delete load balancer %s(%s): %w","messagePattern":"failed to delete load balancer (.+?)\\((.+?)\\): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/resources/hetzner/resources.go","lineNumber":273,"sourceCode":"\tclient := c.FirewallClient()\n\tfirewall := r.Obj.(*hcloud.Firewall)\n\t_, err := client.Delete(context.TODO(), firewall)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to delete firewall %s(%s): %w\", r.Name, r.ID, err)\n\t}\n\n\treturn nil\n}\n\nfunc deleteLoadBalancer(cloud fi.Cloud, r *resources.Resource) error {\n\tklog.Infof(\"Deleting LoadBalancer: %s(%s)\", r.Name, r.ID)\n\n\tc := cloud.(hetzner.HetznerCloud)\n\tclient := c.LoadBalancerClient()\n\tloadBalancer := r.Obj.(*hcloud.LoadBalancer)\n\t_, err := client.Delete(context.TODO(), loadBalancer)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to delete load balancer %s(%s): %w\", r.Name, r.ID, err)\n\t}\n\n\treturn nil\n}\n\nfunc deleteServer(cloud fi.Cloud, r *resources.Resource) error {\n\tctx := context.TODO()\n\n\tklog.Infof(\"Deleting Server: %s(%s)\", r.Name, r.ID)\n\n\tc := cloud.(hetzner.HetznerCloud)\n\tserverClient := c.ServerClient()\n\tactionClient := c.ActionClient()\n\n\tserver := r.Obj.(*hcloud.Server)\n\tresult, _, err := serverClient.DeleteWithResult(ctx, server)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to delete server %s(%s): %w\", r.Name, r.ID, err)","sourceCodeStart":255,"sourceCodeEnd":291,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/resources/hetzner/resources.go#L255-L291","documentation":"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.","triggerScenarios":"client.Delete(ctx, loadBalancer) fails: load balancer still has targets/services attached, invalid token, rate limiting, or already deleted externally.","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"lb, _, err := c.LoadBalancer.Get(ctx, name)\nif err != nil { return err }\nif lb != nil && len(lb.Targets) > 0 {\n    return fmt.Errorf(\"load balancer %s still has %d targets\", name, len(lb.Targets))\n}","typeGuard":"func isRateLimited(err error) bool {\n    var hErr hcloud.Error\n    return errors.As(err, &hErr) && hErr.Code == hcloud.ErrorCodeRateLimitExceeded\n}","tryCatchPattern":"for attempt := 0; attempt < 3; attempt++ {\n    err := deleteLoadBalancer(...)\n    if err == nil { return nil }\n    var hErr hcloud.Error\n    if errors.As(err, &hErr) && (hErr.Code == hcloud.ErrorCodeNotFound || hErr.Code == hcloud.ErrorCodeRateLimitExceeded) {\n        time.Sleep(time.Duration(1<<attempt) * time.Second)\n        continue\n    }\n    return err\n}\nreturn err","preventionTips":["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."],"tags":["hetzner","load-balancer","deletion","cloud-api"],"backgroundTag":"hcloud-api-delete-failed","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"}