kubernetes/kops · error
found SSH key %q in Akamai (Linode), but public key data did
Error message
found SSH key %q in Akamai (Linode), but public key data did not match
What it means
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.
Source
Thrown at upup/pkg/fi/cloudup/linodetasks/sshkey.go:87
if matched == nil {
return nil, nil
}
actual := &SSHKey{
ID: new(matched.ID),
Name: new(matched.Label),
Lifecycle: s.Lifecycle,
}
if s.PublicKey != nil {
expectedPublicKey, err := fi.ResourceAsString(*s.PublicKey)
if err != nil {
return nil, fmt.Errorf("error rendering SSH key data: %w", err)
}
if strings.TrimSpace(expectedPublicKey) != strings.TrimSpace(matched.SSHKey) {
return nil, fmt.Errorf("found SSH key %q in Akamai (Linode), but public key data did not match", name)
}
// Avoid spurious changes.
actual.PublicKey = s.PublicKey
}
return actual, nil
}
func (e *SSHKey) Run(c *fi.CloudupContext) error {
return fi.CloudupDefaultDeltaRunMethod(e, c)
}
func (_ *SSHKey) CheckChanges(actual, expected, changes *SSHKey) error {
if actual != nil {
if changes.ID != nil {
return fi.CannotChangeField("ID")
}View on GitHub (pinned to 4c8573c808)
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
Example fix
// before: local id_rsa.pub rotated but Linode key still old // after: // linode-cli sshkeys delete <old-key-id> // kops update cluster --yes # recreates key with new material
Defensive patterns
Strategy: validation
Validate before calling
remote, _ := client.ListSSHKeys(ctx, nil)
local, _ := os.ReadFile(pubKeyPath)
for _, k := range remote {
if k.Label == name && strings.TrimSpace(k.SSHKey) != strings.TrimSpace(string(local)) {
return fmt.Errorf("key %q drifted; reconcile before applying", name)
}
} Try / catch
_, err := task.Find(c)
if err != nil && strings.Contains(err.Error(), "public key data did not match") {
// delete the remote key or restore local key, then re-run update
return err
} Prevention
- 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
When it happens
Trigger: A Linode SSH key with the same label exists whose SSHKey value (trimmed) differs from the trimmed contents of s.PublicKey during Find().
Common situations: 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.
Related errors
- found multiple SSH keys named %q
- error rendering SSH key data: %w
- error creating Akamai (Linode) SSH key %q: %w
- error parsing Akamai (Linode) %s ID %q: %w
- error listing Akamai (Linode) instances: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/00190eabfa922810.
Report an issue: GitHub.