{"record":{"id":"834a57791e522f87","repo":"kubernetes/kops","slug":"error-creating-sshkey-v","errorCode":null,"errorMessage":"error creating SSHKey: %v","messagePattern":"error creating SSHKey: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/awstasks/sshkey.go","lineNumber":169,"sourceCode":"\tctx := context.TODO()\n\tklog.V(2).Infof(\"Creating SSHKey with Name:%q\", *e.Name)\n\n\trequest := &ec2.ImportKeyPairInput{\n\t\tKeyName:           e.Name,\n\t\tTagSpecifications: awsup.EC2TagSpecification(ec2types.ResourceTypeKeyPair, e.Tags),\n\t}\n\n\tif e.PublicKey != nil {\n\t\td, err := fi.ResourceAsBytes(e.PublicKey)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error rendering SSHKey PublicKey: %v\", err)\n\t\t}\n\t\trequest.PublicKeyMaterial = d\n\t}\n\n\tresponse, err := cloud.EC2().ImportKeyPair(ctx, request)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error creating SSHKey: %v\", err)\n\t}\n\n\te.KeyFingerprint = response.KeyFingerprint\n\te.ID = response.KeyPairId\n\n\treturn nil\n}\n\nfunc (_ *SSHKey) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *SSHKey) error {\n\tif a == nil {\n\t\treturn e.createKeypair(t.Cloud)\n\t}\n\n\tif !e.Shared {\n\t\treturn t.AddAWSTags(*e.ID, e.Tags)\n\t}\n\treturn nil\n}","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/awstasks/sshkey.go#L151-L187","documentation":"createKeypair calls ec2.ImportKeyPair to register the public key with AWS; any API failure is wrapped as \"error creating SSHKey\". Note ImportKeyPair does NOT fail on duplicate names in modern EC2 (it errors InvalidKeyPair.Duplicate only in some paths), so most failures are permission, format, or throttling related.","triggerScenarios":"cloud.EC2().ImportKeyPair returns an error: UnauthorizedOperation (missing ec2:ImportKeyPair), InvalidPublicKeyMaterial.Malformed (bad key format), throttling, or unsupported key format for the region.","commonSituations":"kOps IAM policy missing ec2:ImportKeyPair; key generated with an algorithm EC2 rejects; passing a private key's bytes; transient AWS errors during large applies.","solutions":["Check the wrapped AWS error code and fix accordingly (IAM permission vs. key format).","Add ec2:ImportKeyPair to the kOps IAM policy if UnauthorizedOperation.","Validate the key locally: ssh-keygen -l -f id_rsa.pub; re-export if malformed.","Retry the apply on throttling/transient errors."],"exampleFix":"// before\n{\"Action\":[\"ec2:CreateKeyPair\",\"ec2:DescribeKeyPairs\"]}\n// after\n{\"Action\":[\"ec2:CreateKeyPair\",\"ec2:ImportKeyPair\",\"ec2:DescribeKeyPairs\",\"ec2:DeleteKeyPair\"]}","handlingStrategy":"try-catch","validationCode":"// pre-flight: permission and key-format checks\naws iam simulate-principal-policy --policy-source-arn <kopsRoleArn> --action-names ec2:ImportKeyPair\nssh-keygen -l -f ~/.ssh/id_rsa.pub","typeGuard":null,"tryCatchPattern":"out, err := runKopsApply()\nif err != nil && strings.Contains(out, \"error creating SSHKey\") {\n    switch {\n    case strings.Contains(out, \"UnauthorizedOperation\"):\n        return fmt.Errorf(\"add ec2:ImportKeyPair to the kOps IAM policy\")\n    case strings.Contains(out, \"InvalidPublicKeyMaterial\") || strings.Contains(out, \"malformed\"):\n        return fmt.Errorf(\"fix the public key format before retrying\")\n    default:\n        return retryWithBackoff(runKopsApply) // transient/throttling\n    }\n}","preventionTips":["Grant ec2:ImportKeyPair (plus DescribeKeyPairs/DeleteKeyPair) to the kOps role.","Validate key format locally with ssh-keygen before applying.","Retry applies on transient AWS errors; key import is safe to re-attempt."],"tags":["aws","ec2","ssh-key","import-key-pair","api-error"],"backgroundTag":"aws-api-call-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"}