{"record":{"id":"00190eabfa922810","repo":"kubernetes/kops","slug":"found-ssh-key-q-in-akamai-linode-but-public-ke","errorCode":null,"errorMessage":"found SSH key %q in Akamai (Linode), but public key data did not match","messagePattern":"found SSH key %q in Akamai \\(Linode\\), but public key data did not match","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/linodetasks/sshkey.go","lineNumber":87,"sourceCode":"\n\tif matched == nil {\n\t\treturn nil, nil\n\t}\n\n\tactual := &SSHKey{\n\t\tID:        new(matched.ID),\n\t\tName:      new(matched.Label),\n\t\tLifecycle: s.Lifecycle,\n\t}\n\n\tif s.PublicKey != nil {\n\t\texpectedPublicKey, err := fi.ResourceAsString(*s.PublicKey)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"error rendering SSH key data: %w\", err)\n\t\t}\n\n\t\tif strings.TrimSpace(expectedPublicKey) != strings.TrimSpace(matched.SSHKey) {\n\t\t\treturn nil, fmt.Errorf(\"found SSH key %q in Akamai (Linode), but public key data did not match\", name)\n\t\t}\n\n\t\t// Avoid spurious changes.\n\t\tactual.PublicKey = s.PublicKey\n\t}\n\n\treturn actual, nil\n}\n\nfunc (e *SSHKey) Run(c *fi.CloudupContext) error {\n\treturn fi.CloudupDefaultDeltaRunMethod(e, c)\n}\n\nfunc (_ *SSHKey) CheckChanges(actual, expected, changes *SSHKey) error {\n\tif actual != nil {\n\t\tif changes.ID != nil {\n\t\t\treturn fi.CannotChangeField(\"ID\")\n\t\t}","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/linodetasks/sshkey.go#L69-L105","documentation":"Find() found an SSH key with the matching label in Linode, but its key material differs from the local PublicKey. Because kops cannot safely adopt a key whose data doesn't match, it refuses with this error rather than silently replacing the key.","triggerScenarios":"A Linode SSH key with the same label exists whose SSHKey value (trimmed) differs from the trimmed contents of s.PublicKey during Find().","commonSituations":"User rotated the local SSH key but kept the same label, a different machine with a different key file ran kops against the same cluster, or whitespace/key-comment changes were made to the .pub file.","solutions":["Make the local public key file content match the key registered in Linode (restore original key or update the key in Linode Cloud Manager)","Delete the mismatched Linode key and let kops recreate it (linode-cli sshkeys delete <id>)","Generate a new key, register it, and update the cluster spec consistently","Check for trailing-comment differences — the comparison is of full key strings after trimming"],"exampleFix":"// before: local id_rsa.pub rotated but Linode key still old\n// after:\n//   linode-cli sshkeys delete <old-key-id>\n//   kops update cluster --yes  # recreates key with new material","handlingStrategy":"validation","validationCode":"remote, _ := client.ListSSHKeys(ctx, nil)\nlocal, _ := os.ReadFile(pubKeyPath)\nfor _, k := range remote {\n    if k.Label == name && strings.TrimSpace(k.SSHKey) != strings.TrimSpace(string(local)) {\n        return fmt.Errorf(\"key %q drifted; reconcile before applying\", name)\n    }\n}","typeGuard":null,"tryCatchPattern":"_, err := task.Find(c)\nif err != nil && strings.Contains(err.Error(), \"public key data did not match\") {\n    // delete the remote key or restore local key, then re-run update\n    return err\n}","preventionTips":["Never rotate key material under the same label — delete and recreate","Keep the same key file path in spec across operators/machines","Avoid editing comments in .pub files after cluster creation"],"tags":["linode","akamai","sshkey","drift","mismatch"],"backgroundTag":"ssh-key-mismatch","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"}