{"record":{"id":"38cf7e15c278ad56","repo":"kubernetes/kops","slug":"failed-to-list-load-balancers-w","errorCode":null,"errorMessage":"failed to list load balancers: %w","messagePattern":"failed to list load balancers: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/resources/hetzner/resources.go","lineNumber":148,"sourceCode":"\t\t\tID:      strconv.FormatInt(firewall.ID, 10),\n\t\t\tType:    resourceTypeFirewall,\n\t\t\tDeleter: deleteFirewall,\n\t\t\tObj:     firewall,\n\t\t}\n\n\t\tresourceTrackers = append(resourceTrackers, resourceTracker)\n\t}\n\n\treturn resourceTrackers, nil\n}\n\nfunc listLoadBalancers(cloud fi.Cloud, clusterName string) ([]*resources.Resource, error) {\n\tc := cloud.(hetzner.HetznerCloud)\n\tvar resourceTrackers []*resources.Resource\n\n\tloadBalancers, err := c.GetLoadBalancers(clusterName)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to list load balancers: %w\", err)\n\t}\n\n\tfor _, loadBalancer := range loadBalancers {\n\t\tresourceTracker := &resources.Resource{\n\t\t\tName:    loadBalancer.Name,\n\t\t\tID:      strconv.FormatInt(loadBalancer.ID, 10),\n\t\t\tType:    resourceTypeLoadBalancer,\n\t\t\tDeleter: deleteLoadBalancer,\n\t\t\tObj:     loadBalancer,\n\t\t}\n\n\t\tresourceTrackers = append(resourceTrackers, resourceTracker)\n\t}\n\n\treturn resourceTrackers, nil\n}\n\nfunc listServers(cloud fi.Cloud, clusterName string) ([]*resources.Resource, error) {","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/resources/hetzner/resources.go#L130-L166","documentation":"Returned by listLoadBalancers when GetLoadBalancers(clusterName) fails while enumerating Hetzner Cloud Load Balancers during cluster deletion discovery. Without a successful load_balancers.list, kops cannot identify load balancers tagged for the cluster and aborts. The cause is in the wrapped hcloud error.","triggerScenarios":"Hetzner load_balancers.list API call fails: bad/missing API token, rate limit exceeded, Hetzner API outage, or network failure.","commonSituations":"Token lacks read permissions on the project; token rotated by ops team but kops env not updated; hitting Hetzner API rate limits during automated cleanup jobs; transient API errors.","solutions":["Verify token validity: curl -H \"Authorization: Bearer $HCLOUD_TOKEN\" https://api.hetzner.cloud/v1/load_balancers.","Issue a fresh project-scoped read/write token if the current one is invalid or under-scoped.","Back off and retry on 429/5xx; add delays between consecutive kops cloud operations.","Check Hetzner status page for outages before debugging credentials."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"resp, err := hc.Get(\"https://api.hetzner.cloud/v1/load_balancers\")\nif err != nil || resp.StatusCode != 200 {\n    return fmt.Errorf(\"load balancer API precheck failed; check token and connectivity\")\n}","typeGuard":"var hErr hcloud.Error\nif errors.As(err, &hErr) && hErr.Code == hcloud.ErrorCodeUnauthorized {\n    // invalid token\n}","tryCatchPattern":"lbs, err := c.GetLoadBalancers(clusterName)\nvar hErr hcloud.Error\nif errors.As(err, &hErr) {\n    if hErr.Code == hcloud.ErrorCodeRateLimitExceeded || (isServerError(hErr)) {\n        time.Sleep(backoff)\n        lbs, err = c.GetLoadBalancers(clusterName)\n    }\n}","preventionTips":["Verify token validity with a list call before invoking kops delete.","Use read/write tokens scoped to the cluster's project.","Add jittered retries for transient API errors in automation.","Check Hetzner status page when multiple list calls fail together."],"tags":["hetzner","load-balancer","api","cloud-provider"],"backgroundTag":"cloud-api-auth-failure","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}