{"record":{"id":"d49face6af8e710d","repo":"kubernetes/kops","slug":"error-listing-keypair-v","errorCode":null,"errorMessage":"error listing keypair: %v","messagePattern":"error listing keypair: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/openstack/keypair.go","lineNumber":40,"sourceCode":"\n\t\"github.com/gophercloud/gophercloud/v2/openstack/compute/v2/keypairs\"\n\t\"k8s.io/apimachinery/pkg/util/wait\"\n\t\"k8s.io/kops/util/pkg/vfs\"\n)\n\nfunc (c *openstackCloud) GetKeypair(name string) (*keypairs.KeyPair, error) {\n\treturn getKeypair(c, name)\n}\n\nfunc getKeypair(c OpenstackCloud, name string) (*keypairs.KeyPair, error) {\n\tvar k *keypairs.KeyPair\n\tdone, err := vfs.RetryWithBackoff(readBackoff, func() (bool, error) {\n\t\trs, err := keypairs.Get(context.TODO(), c.ComputeClient(), name, nil).Extract()\n\t\tif err != nil {\n\t\t\tif isNotFound(err) {\n\t\t\t\treturn true, nil\n\t\t\t}\n\t\t\treturn false, fmt.Errorf(\"error listing keypair: %v\", err)\n\t\t}\n\t\tk = rs\n\t\treturn true, nil\n\t})\n\tif err != nil {\n\t\treturn k, err\n\t} else if done {\n\t\treturn k, nil\n\t} else {\n\t\treturn k, wait.ErrWaitTimeout\n\t}\n}\n\nfunc (c *openstackCloud) CreateKeypair(opt keypairs.CreateOptsBuilder) (*keypairs.KeyPair, error) {\n\treturn createKeypair(c, opt)\n}\n\nfunc createKeypair(c OpenstackCloud, opt keypairs.CreateOptsBuilder) (*keypairs.KeyPair, error) {","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/openstack/keypair.go#L22-L58","documentation":"getKeypair wraps errors from keypairs.Get (Nova os-keypairs API) with this message, except when the keypair is simply not found (404), which returns nil,nil. Any other failure — auth, connectivity, API error — during the readBackoff retry loop surfaces as this error.","triggerScenarios":"keypairs.Get fails with a non-404 error: invalid/expired token, compute endpoint unreachable, or Nova keypair API returning 403/5xx while looking up the named keypair.","commonSituations":"Cluster SSH key lookup during instance creation with expired Keystone credentials; hardened RBAC policy denying keypair GET; network outage to the compute API.","solutions":["Read the wrapped %v error to identify auth vs connectivity vs policy failure","Re-authenticate (valid OS_* credentials/clouds.yaml) if it's a 401","If 403, grant the project/service user permission to read keypairs or pre-provision the keypair under the expected name","Retry after fixing connectivity; a 404 is already handled as 'keypair absent', not an error"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// confirm auth and keypair visibility before lookups\nerr := shell.Exec(\"openstack keypair show \" + keypairName) // non-404 failures caught here early","typeGuard":null,"tryCatchPattern":"k, err := GetKeypair(cloud, name)\nif err != nil {\n    if strings.Contains(err.Error(), \"error listing keypair\") {\n        // treat as transient/API issue; note: not-found returns (nil, nil) already\n        return retryAfterBackoff(func() error { _, err = GetKeypair(cloud, name); return err })\n    }\n    return err\n}","preventionTips":["Refresh tokens before long-running cluster operations","Pre-provision SSH keypairs under kops' expected name so 404 (absent) is the common path","Verify RBAC allows keypair reads for the service user","Distinguish 404 (handled) from other statuses in wrapped error strings"],"tags":["openstack","keypairs","ssh","api"],"backgroundTag":"openstack-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"}