{"record":{"id":"9965cff965062a44","repo":"kubernetes/kops","slug":"error-listing-sshkeys-v","errorCode":null,"errorMessage":"error listing SSHKeys: %v","messagePattern":"error listing SSHKeys: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/awstasks/sshkey.go","lineNumber":69,"sourceCode":"\nfunc (e *SSHKey) CompareWithID() *string {\n\treturn e.Name\n}\n\nfunc (e *SSHKey) Find(c *fi.CloudupContext) (*SSHKey, error) {\n\tcloud := awsup.GetCloud(c)\n\n\treturn e.find(c.Context(), cloud)\n}\n\nfunc (e *SSHKey) find(ctx context.Context, cloud awsup.AWSCloud) (*SSHKey, error) {\n\trequest := &ec2.DescribeKeyPairsInput{\n\t\tKeyNames: []string{fi.ValueOf(e.Name)},\n\t}\n\n\tresponse, err := cloud.EC2().DescribeKeyPairs(ctx, request)\n\tif err != nil && awsup.AWSErrorCode(err) != \"InvalidKeyPair.NotFound\" {\n\t\treturn nil, fmt.Errorf(\"error listing SSHKeys: %v\", err)\n\t}\n\n\tif response == nil || len(response.KeyPairs) == 0 {\n\t\tif e.IsExistingKey() && *e.Name != \"\" {\n\t\t\treturn nil, fmt.Errorf(\"unable to find specified SSH key %q\", *e.Name)\n\t\t}\n\t\treturn nil, nil\n\t}\n\n\tif len(response.KeyPairs) != 1 {\n\t\treturn nil, fmt.Errorf(\"Found multiple SSHKeys with Name %q\", *e.Name)\n\t}\n\n\tk := response.KeyPairs[0]\n\tactual := &SSHKey{\n\t\tID:             k.KeyPairId,\n\t\tName:           k.KeyName,\n\t\tKeyFingerprint: k.KeyFingerprint,","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/awstasks/sshkey.go#L51-L87","documentation":"SSHKey.find calls ec2.DescribeKeyPairs to locate the key by name. Any API error other than InvalidKeyPair.NotFound aborts the Find with \"error listing SSHKeys\". Find is what lets kOps compare cloud state to the spec, so this blocks reconciliation of SSH keys entirely.","triggerScenarios":"cloud.EC2().DescribeKeyPairs returns an error with a code other than InvalidKeyPair.NotFound: UnauthorizedOperation, AuthFailure (bad credentials), request throttling, or network failure to EC2.","commonSituations":"Expired/missing AWS credentials; kOps IAM role missing ec2:DescribeKeyPairs; corporate proxy or VPC endpoint blocking EC2 API; regional outage.","solutions":["Fix the wrapped AWS error: refresh credentials (aws sts get-caller-identity) or add ec2:DescribeKeyPairs to the IAM policy.","Retry after checking network/EC2 endpoint reachability from the machine running kOps.","If throttled, reduce concurrency or retry later.","Verify AWS_REGION/default region settings are valid."],"exampleFix":"// before\nexport AWS_PROFILE=stale-profile\n// after\nexport AWS_PROFILE=valid-profile && aws sts get-caller-identity","handlingStrategy":"try-catch","validationCode":"// verify credentials and permissions before kops\naws sts get-caller-identity\naws ec2 describe-key-pairs --query 'KeyPairs[].KeyName'","typeGuard":null,"tryCatchPattern":"out, err := exec.Command(\"kops\", \"apply\").CombinedOutput()\nif err != nil && strings.Contains(string(out), \"error listing SSHKeys\") {\n    // AWS-level auth/permission/network failure; surface wrapped code\n    return fmt.Errorf(\"EC2 API unreachable during SSH key discovery: %s\", out)\n}","preventionTips":["Run aws sts get-caller-identity to validate credentials before applies.","Grant ec2:DescribeKeyPairs to the kOps role.","Check proxy/VPC endpoint config for EC2 API reachability."],"tags":["aws","ec2","ssh-key","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"}