{"record":{"id":"6c3282f77509543a","repo":"kubernetes/kops","slug":"error-creating-akamai-linode-ssh-key-q-w","errorCode":null,"errorMessage":"error creating Akamai (Linode) SSH key %q: %w","messagePattern":"error creating Akamai \\(Linode\\) SSH key %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/linodetasks/sshkey.go","lineNumber":148,"sourceCode":"\tif name == \"\" {\n\t\treturn fi.RequiredField(\"Name\")\n\t}\n\n\tif expected.PublicKey == nil {\n\t\treturn fi.RequiredField(\"PublicKey\")\n\t}\n\n\tpublicKey, err := fi.ResourceAsString(*expected.PublicKey)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error rendering SSH key data: %w\", err)\n\t}\n\n\tcreated, err := t.Cloud.Client().CreateSSHKey(context.Background(), linodego.SSHKeyCreateOptions{\n\t\tLabel:  name,\n\t\tSSHKey: strings.TrimSpace(publicKey),\n\t})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error creating Akamai (Linode) SSH key %q: %w\", name, err)\n\t}\n\n\texpected.ID = new(created.ID)\n\tklog.V(2).Infof(\"Created Akamai (Linode) SSH key %q (id=%d)\", created.Label, created.ID)\n\n\treturn nil\n}\n","sourceCodeStart":130,"sourceCodeEnd":156,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/linodetasks/sshkey.go#L130-L156","documentation":"SSHKey.RenderLinode wraps the linodego CreateSSHKey error when uploading a new SSH public key to the Akamai (Linode) account. It fires when the API rejects creation — invalid key material, duplicate label, auth, or rate limits — leaving the task unable to create the key.","triggerScenarios":"cloud.Client().CreateSSHKey returns an error — e.g. invalid Linode API token, 429 rate limit, or the SSHKey payload is rejected by the API.","commonSituations":"Expired/incorrect LINODE_API_TOKEN, account hitting SSH key limits, or network/API outage during kops update.","solutions":["Verify the Linode API token is valid and has write scopes (check LINODE_API_TOKEN env var)","Check the wrapped inner error for HTTP status; retry after a 429 rate limit","Validate the public key format is a valid OpenSSH public key","Check https://status.linode.com for API incidents"],"exampleFix":"// before\nexport LINODE_API_TOKEN=expired-token\n// after\nexport LINODE_API_TOKEN=$(cat ~/.linode-token)  # fresh token with RW scope","handlingStrategy":"retry","validationCode":"if os.Getenv(\"LINODE_API_TOKEN\") == \"\" { return errors.New(\"LINODE_API_TOKEN not set\") }\n// optionally: ping the API with client.ListSSHKeys before creating","typeGuard":null,"tryCatchPattern":"created, err := client.CreateSSHKey(ctx, opts)\nif err != nil {\n    if lw, ok := err.(*linodego.Error); ok && lw.Code == 429 {\n        time.Sleep(retryAfter); return retry()\n    }\n    return fmt.Errorf(\"error creating Akamai (Linode) SSH key %q: %w\", name, err)\n}","preventionTips":["Use a fresh Linode API token with RW scopes","Add exponential backoff for 429/5xx responses","Validate key format before upload","Watch Linode status page during CI runs"],"tags":["linode","akamai","sshkey","api-error","authentication"],"backgroundTag":"api-request-failed","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"}