{"record":{"id":"c01425bbfc8b289d","repo":"kubernetes/kops","slug":"failed-to-list-servers-w-c01425","errorCode":null,"errorMessage":"failed to list servers: %w","messagePattern":"failed to list servers: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/hetzner/cloud.go","lineNumber":347,"sourceCode":"\t\t\t\tklog.Warningf(\"Server group %q has no corresponding instance group\", name)\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tcloudInstanceGroups[instanceGroup.Name], err = buildCloudInstanceGroup(instanceGroup, serverGroup, nodeMap)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to build cloud instance group for instance group %q: %w\", instanceGroup.Name, err)\n\t\t}\n\t}\n\n\treturn cloudInstanceGroups, nil\n}\n\n// findServerGroups finds all server groups belonging to the cluster\nfunc findServerGroups(c *hetznerCloudImplementation, clusterName string) (map[string][]*hcloud.Server, error) {\n\tservers, err := c.GetServers(clusterName)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to list servers: %w\", err)\n\t}\n\n\tserverGroups := make(map[string][]*hcloud.Server)\n\tfor _, server := range servers {\n\t\tinstanceGroupNameLabel, ok := server.Labels[TagKubernetesInstanceGroup]\n\t\tif !ok {\n\t\t\tklog.Warningf(\"failed to find instance group name for server %s(%d)\", server.Name, server.ID)\n\t\t\tcontinue\n\t\t}\n\n\t\tinstanceGroupName := fmt.Sprintf(\"%s-%s\", clusterName, instanceGroupNameLabel)\n\t\tserverGroups[instanceGroupName] = append(serverGroups[instanceGroupName], server)\n\t}\n\n\treturn serverGroups, nil\n}\n\nfunc buildCloudInstanceGroup(ig *kops.InstanceGroup, sg []*hcloud.Server, nodeMap map[string]*v1.Node) (*cloudinstances.CloudInstanceGroup, error) {","sourceCodeStart":329,"sourceCodeEnd":365,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/hetzner/cloud.go#L329-L365","documentation":"findServerGroups wraps any error returned by GetServers (the Hetzner hcloud /servers list call) with context before propagating it to GetCloudGroups. It means the Hetzner Cloud API listing of servers for the cluster failed, so no cloud instance groups could be computed.","triggerScenarios":"c.GetServers(clusterName) returns an error: Hetzner API HTTP error, invalid/expired HCLOUD_TOKEN, network timeout, or API rate limiting during the ListServers request.","commonSituations":"Wrong or revoked API token in HCLOUD_TOKEN env; Hetzner API outage; network egress blocked from the CI/bastion host; hitting hcloud API rate limits on large clusters.","solutions":["Check the wrapped error for the root cause (401 => invalid HCLOUD_TOKEN, timeouts => network, 429 => rate limit).","Verify HCLOUD_TOKEN is valid: `curl -H \"Authorization: Bearer $HCLOUD_TOKEN\" https://api.hetzner.cloud/v1/servers`.","Retry the operation; transient network/API failures are common.","If rate limited, back off and reduce polling frequency."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// preflight\nconst ok = process.env.HCLOUD_TOKEN && (await fetch('https://api.hetzner.cloud/v1/servers',{headers:{Authorization:`Bearer ${process.env.HCLOUD_TOKEN}`}})).ok;","typeGuard":null,"tryCatchPattern":"var groups *map[string][]*hcloud.Server\nfor i := 0; i < 3; i++ {\n  groups, err = findServerGroups(c, clusterName)\n  if err == nil { break }\n  time.Sleep(backoff(i)) // retry transient API failures\n}\nif err != nil { return fmt.Errorf(\"failed to list servers: %w\", err) }","preventionTips":["Validate HCLOUD_TOKEN before running cluster operations.","Retry list operations with backoff; Hetzner API has transient failures and rate limits.","Monitor Hetzner Cloud status page during maintenance windows."],"tags":["hetzner","api","cloud-groups"],"backgroundTag":"cloud-api-request-failed","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"}