{"record":{"id":"60fb8a828ef8d632","repo":"kubernetes/kops","slug":"failed-to-get-ssh-keys-matching-label-selector-q","errorCode":null,"errorMessage":"failed to get SSH keys matching label selector %q: %w","messagePattern":"failed to get SSH keys matching label selector %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/hetzner/cloud.go","lineNumber":147,"sourceCode":"\n// VolumeClient returns an implementation of hetzner.VolumeClient\nfunc (c *hetznerCloudImplementation) VolumeClient() hcloud.VolumeClient {\n\treturn c.Client.Volume\n}\n\nfunc (c *hetznerCloudImplementation) GetSSHKeys(clusterName string) ([]*hcloud.SSHKey, error) {\n\tclient := c.SSHKeyClient()\n\n\tlabelSelector := TagKubernetesClusterName + \"=\" + clusterName\n\tlistOptions := hcloud.ListOpts{\n\t\tPerPage:       50,\n\t\tLabelSelector: labelSelector,\n\t}\n\tsshKeyListOpts := hcloud.SSHKeyListOpts{ListOpts: listOptions}\n\n\tmatches, err := client.AllWithOpts(context.TODO(), sshKeyListOpts)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get SSH keys matching label selector %q: %w\", labelSelector, err)\n\t}\n\n\treturn matches, nil\n}\n\nfunc (c *hetznerCloudImplementation) GetNetworks(clusterName string) ([]*hcloud.Network, error) {\n\tclient := c.NetworkClient()\n\n\tlabelSelector := TagKubernetesClusterName + \"=\" + clusterName\n\tlistOptions := hcloud.ListOpts{\n\t\tPerPage:       50,\n\t\tLabelSelector: labelSelector,\n\t}\n\tnetworkListOptions := hcloud.NetworkListOpts{ListOpts: listOptions}\n\n\tmatches, err := client.AllWithOpts(context.TODO(), networkListOptions)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get networks matching label selector %q: %w\", labelSelector, err)","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/hetzner/cloud.go#L129-L165","documentation":"hetznerCloudImplementation.GetSSHKeys lists Hetzner Cloud SSH keys filtered by a label selector using the hcloud client's AllWithOpts. If the paginated listing fails, the error is wrapped with the selector for context. This is an API-level failure, not 'no keys found'.","triggerScenarios":"client.AllWithOpts(context.TODO(), sshKeyListOpts) errors: invalid hcloud API token, network failure to api.hetzner.cloud, rate limiting, or a malformed label selector string.","commonSituations":"Expired or revoked HCLOUD_API_TOKEN; wrong token for the project containing the cluster; corporate proxy/firewall blocking api.hetzner.cloud; typo in labelSelector producing a 400 from the API; Hetzner API rate limits during large applies.","solutions":["Verify the Hetzner API token is valid: `hcloud ssh-key list` with the same token/env","Check network connectivity/proxy settings to api.hetzner.cloud","Validate the label selector syntax (e.g. 'kubernetes.io/cluster/<name>=<cluster-id>')","Wait and retry if rate-limited (HTTP 429 in wrapped error)"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"test -n \"$HCLOUD_TOKEN\" && curl -s -H \"Authorization: Bearer $HCLOUD_TOKEN\" https://api.hetzner.cloud/v1/ssh_keys | head -c 200","typeGuard":null,"tryCatchPattern":"keys, err := GetSSHKeys(ctx, selector)\nif err != nil { return fmt.Errorf(\"hetzner ssh key lookup failed (check HCLOUD_TOKEN/connectivity): %w\", err) }","preventionTips":["Validate HCLOUD_TOKEN before running kops","Test label selectors with the hcloud CLI first","Check Hetzner API status page during CI failures","Back off on 429 rate-limit responses"],"tags":["hetzner","ssh-keys","cloud-api"],"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"}