{"record":{"id":"de8832f9de802d93","repo":"kubernetes/kops","slug":"error-listing-akamai-linode-ssh-keys-w-de8832","errorCode":null,"errorMessage":"error listing Akamai (Linode) SSH keys: %w","messagePattern":"error listing Akamai \\(Linode\\) SSH keys: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/linodetasks/sshkey.go","lineNumber":54,"sourceCode":"}\n\nvar _ fi.CloudupTask = &SSHKey{}\nvar _ fi.CompareWithID = &SSHKey{}\n\nfunc (s *SSHKey) CompareWithID() *string {\n\treturn s.Name\n}\n\nfunc (s *SSHKey) Find(c *fi.CloudupContext) (*SSHKey, error) {\n\tcloud := c.T.Cloud.(linode.LinodeCloud)\n\tname := fi.ValueOf(s.Name)\n\tif name == \"\" {\n\t\treturn nil, fmt.Errorf(\"SSHKey.Name is required\")\n\t}\n\n\tkeys, err := cloud.Client().ListSSHKeys(c.Context(), nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error listing Akamai (Linode) SSH keys: %w\", err)\n\t}\n\n\tvar matched *linodego.SSHKey\n\tfor i := range keys {\n\t\tkey := &keys[i]\n\t\tif key.Label != name {\n\t\t\tcontinue\n\t\t}\n\n\t\tif matched != nil {\n\t\t\treturn nil, fmt.Errorf(\"found multiple SSH keys named %q\", name)\n\t\t}\n\t\tmatched = key\n\t}\n\n\tif matched == nil {\n\t\treturn nil, nil\n\t}","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/linodetasks/sshkey.go#L36-L72","documentation":"SSHKey.Find wraps the linodego ListSSHKeys error while locating an existing Akamai (Linode) SSH key by label. It fires when the Linode API call fails (auth, rate limit, network), aborting reconciliation of the SSHKey task because current state cannot be determined.","triggerScenarios":"cloud.Client().ListSSHKeys fails — invalid/expired token, insufficient scopes, network failure, or Linode API error — during Find.","commonSituations":"Expired LINODE_TOKEN, a token without account read scope, firewall/proxy blocking api.linode.com from a CI environment.","solutions":["Verify the API token is valid and has read scopes","Check connectivity to api.linode.com","Retry the apply if the API error was transient"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// sanity-check API access before running apply\nif _, err := client.ListSSHKeys(ctx, nil); err != nil { return err }","typeGuard":null,"tryCatchPattern":"keys, err := cloud.Client().ListSSHKeys(ctx, nil)\nif err != nil {\n    // retry with backoff for transient errors, then wrap and fail\n    return nil, fmt.Errorf(\"error listing Akamai (Linode) SSH keys: %w\", err)\n}","preventionTips":["Keep LINODE_TOKEN fresh and correctly scoped","Ensure egress to api.linode.com from the machine running kops","Handle 429 rate limits with backoff in automation"],"tags":["ssh","linode","api"],"backgroundTag":"cloud-api-list-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"}