{"record":{"id":"cceca83d309c122c","repo":"kubernetes/kops","slug":"found-multiple-ssh-keys-named-q","errorCode":null,"errorMessage":"found multiple SSH keys named %q","messagePattern":"found multiple SSH keys named %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/linodetasks/sshkey.go","lineNumber":65,"sourceCode":"\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}\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)","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/linodetasks/sshkey.go#L47-L83","documentation":"Find() iterates all Linode SSH keys registered on the account looking for one whose Label matches the requested name. If a second key with the same label is encountered after one was already matched, the ambiguity is unrecoverable, so it aborts with this error instead of silently picking one.","triggerScenarios":"Two or more linodego SSH keys exist on the account with identical Label values and kops calls Find for the SSHKey task with that label name.","commonSituations":"Manually re-adding the same cluster SSH key in the Linode Cloud Manager after a failed/aborted kops create, or sharing one Linode account across multiple clusters that each registered a key with the same label.","solutions":["List SSH keys on the account and delete or rename duplicates so only one key has that label (linode-cli sshkeys list / Cloud Manager)","Delete stale keys from previous aborted cluster creates","Use a unique cluster/key name in the kops cluster spec so labels don't collide","If in dry-run only, this still fails: clean the account before running kops update"],"exampleFix":"// before: two keys labeled 'mycluster-key' on the account\n// after:\n//   linode-cli sshkeys list  # identify duplicate labels\n//   linode-cli sshkeys delete <duplicate-id>","handlingStrategy":"validation","validationCode":"keys, _ := client.ListSSHKeys(ctx, nil)\ncount := 0\nfor _, k := range keys {\n    if k.Label == name { count++ }\n}\nif count > 1 { return fmt.Errorf(\"duplicate SSH key labels for %q: clean up first\", name) }","typeGuard":"func uniqueSSHKey(keys []linodego.SSHKey, name string) *linodego.SSHKey {\n    var m *linodego.SSHKey\n    for i := range keys {\n        if keys[i].Label != name { continue }\n        if m != nil { return nil }\n        m = &keys[i]\n    }\n    return m\n}","tryCatchPattern":null,"preventionTips":["Give each cluster's SSH key a globally unique label","Clean up keys after aborted cluster creates","Periodically audit account SSH keys for duplicate labels"],"tags":["linode","akamai","sshkey","duplicate-resource"],"backgroundTag":"duplicate-resource-name","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"}