{"record":{"id":"bbfb510755aa6ece","repo":"kubernetes/kops","slug":"failed-to-list-firewalls-w","errorCode":null,"errorMessage":"failed to list firewalls: %w","messagePattern":"failed to list firewalls: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/resources/hetzner/resources.go","lineNumber":124,"sourceCode":"\t\t\tID:      strconv.FormatInt(network.ID, 10),\n\t\t\tType:    resourceTypeNetwork,\n\t\t\tDeleter: deleteNetwork,\n\t\t\tObj:     network,\n\t\t}\n\n\t\tresourceTrackers = append(resourceTrackers, resourceTracker)\n\t}\n\n\treturn resourceTrackers, nil\n}\n\nfunc listFirewalls(cloud fi.Cloud, clusterName string) ([]*resources.Resource, error) {\n\tc := cloud.(hetzner.HetznerCloud)\n\tvar resourceTrackers []*resources.Resource\n\n\tfirewalls, err := c.GetFirewalls(clusterName)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to list firewalls: %w\", err)\n\t}\n\n\tfor _, firewall := range firewalls {\n\t\tresourceTracker := &resources.Resource{\n\t\t\tName:    firewall.Name,\n\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) {","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/resources/hetzner/resources.go#L106-L142","documentation":"Returned by listFirewalls when GetFirewalls(clusterName) fails during Hetzner cluster resource discovery. kops lists firewalls to find cluster-scoped ones for deletion; an API failure here stops the discovery phase entirely. The original hcloud SDK error is wrapped with %w for inspection via errors.Is/As.","triggerScenarios":"Hetzner firewalls.list API call errors: authentication failure, rate limiting, API outage, or network interruption between kops and api.hetzner.cloud.","commonSituations":"HCLOUD_TOKEN revoked or mistyped; exceeding Hetzner API rate limits when many delete/verify operations run back-to-back; Hetzner API incident causing 500s.","solutions":["Validate credentials with curl -H \"Authorization: Bearer $HCLOUD_TOKEN\" https://api.hetzner.cloud/v1/firewalls.","If the wrapped error is 429 (rate_limit_exceeded), wait (check X-Ratelimit-Reset header) and retry.","Check status.hetzner.com for ongoing API incidents and retry after resolution.","Ensure a stable network connection / correct HTTPS proxy settings for API access."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if _, err := hc.ListFirewalls(ctx, hcloud.FirewallListOpts{}); err != nil {\n    return fmt.Errorf(\"firewalls precheck failed: %w\", err)\n}","typeGuard":"var hErr hcloud.Error\nif errors.As(err, &hErr) && (hErr.Code == hcloud.ErrorCodeRateLimitExceeded || hErr.Code == hcloud.ErrorCodeUnauthorized) {\n    // classify before deciding retry vs credential fix\n}","tryCatchPattern":"firewalls, err := c.GetFirewalls(clusterName)\nif err != nil {\n    var hErr hcloud.Error\n    if errors.As(err, &hErr) && hErr.Code == hcloud.ErrorCodeRateLimitExceeded {\n        time.Sleep(rateLimitBackoff)\n        firewalls, err = c.GetFirewalls(clusterName)\n    }\n}","preventionTips":["Space out consecutive Hetzner API operations to stay under rate limits.","Verify token read scope for firewalls before delete flows.","Monitor status.hetzner.com during maintenance windows.","Wrap Hetzner calls with exponential backoff retry helpers."],"tags":["hetzner","firewall","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-12T07:17:12.445Z"}