{"record":{"id":"11e78896b15751ea","repo":"kubernetes/kops","slug":"failed-to-find-server-groups-v","errorCode":null,"errorMessage":"failed to find server groups: %v","messagePattern":"failed to find server groups: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/hetzner/cloud.go","lineNumber":314,"sourceCode":"\treturn nil\n}\n\n// ProviderID returns the kOps API identifier for Hetzner Cloud\nfunc (c *hetznerCloudImplementation) ProviderID() kops.CloudProviderID {\n\treturn kops.CloudProviderHetzner\n}\n\n// Region returns the Hetzner Cloud region\nfunc (c *hetznerCloudImplementation) Region() string {\n\treturn c.region\n}\n\nfunc (c *hetznerCloudImplementation) GetCloudGroups(cluster *kops.Cluster, instanceGroups []*kops.InstanceGroup, warnUnmatched bool, nodes []v1.Node) (map[string]*cloudinstances.CloudInstanceGroup, error) {\n\tnodeMap := cloudinstances.GetNodeMap(nodes, cluster)\n\n\tserverGroups, err := findServerGroups(c, cluster.Name)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to find server groups: %v\", err)\n\t}\n\n\tcloudInstanceGroups := make(map[string]*cloudinstances.CloudInstanceGroup)\n\tfor name, serverGroup := range serverGroups {\n\t\tvar instanceGroup *kops.InstanceGroup\n\t\tfor _, ig := range instanceGroups {\n\t\t\tgroupName := fmt.Sprintf(\"%s-%s\", cluster.Name, ig.Name)\n\t\t\tif name == groupName {\n\t\t\t\tinstanceGroup = ig\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif instanceGroup == nil {\n\t\t\tif warnUnmatched {\n\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}","sourceCodeStart":296,"sourceCodeEnd":332,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/hetzner/cloud.go#L296-L332","documentation":"GetCloudGroups builds cloud instance groups from Hetzner servers grouped by the kops/cluster group label; this error is thrown when findServerGroups fails, which itself wraps GetServers (API list) and label-parsing errors. It prevents kOps from mapping cluster servers to instance groups.","triggerScenarios":"GetCloudGroups called during validate/rolling-update when the underlying GetServers API call fails (bad token, rate limit, network) or a server's group label cannot be parsed by findServerGroups.","commonSituations":"Servers missing or having malformed kops.k8s.io/instance-group labels (edited manually in Hetzner console), Hetzner API outages, or invalid credentials during cluster operations.","solutions":["Fix the underlying cause reported by the wrapped error (token, network, rate limit)","Ensure all cluster servers carry the correct kops.k8s.io/instance-group label","Re-apply/repair labels via Hetzner API or recreate affected instances with kOps","Retry the operation once API access is restored"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// ensure all cluster servers carry the group label before building groups\nfor _, s := range servers {\n\tif s.Labels[\"kops.k8s.io/instance-group\"] == \"\" {\n\t\treturn fmt.Errorf(\"server %d missing instance-group label\", s.ID)\n\t}\n}","typeGuard":"var hcloudErr *hcloud.Error\nif errors.As(err, &hcloudErr) {\n\t// distinguish API failures from label-parsing failures\n}","tryCatchPattern":"groups, err := cloud.GetCloudGroups(cluster, igs, warnUnmatched, nodes)\nif err != nil {\n\tvar hErr *hcloud.Error\n\tif errors.As(err, &hErr) && hErr.Code == hcloud.ErrorCodeRateLimit {\n\t\ttime.Sleep(hErr.RateLimit.RetryAfter())\n\t\tgroups, err = cloud.GetCloudGroups(cluster, igs, warnUnmatched, nodes)\n\t}\n}","preventionTips":["Never remove/edit kops.k8s.io labels on Hetzner servers via console","Validate the API token before operations that list servers","Repair label drift with kops tooling or recreate instances","Retry transient API failures with backoff"],"tags":["hetzner","groups","labels","api"],"backgroundTag":"missing-cloud-label","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"}