{"record":{"id":"678c5360b0874458","repo":"kubernetes/kops","slug":"error-listing-sshcredentials-v-678c53","errorCode":null,"errorMessage":"error listing SSHCredentials: %v","messagePattern":"error listing SSHCredentials: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/vfs_castore.go","lineNumber":216,"sourceCode":"\t\tklog.V(2).Infof(\"Skipping key store mirror from %q to %q (same paths)\", c.basedir, basedir)\n\t\treturn nil\n\t}\n\tklog.V(2).Infof(\"Mirroring key store from %q to %q\", c.basedir, basedir)\n\n\tkeysets, err := c.ListKeysets()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfor name, keyset := range keysets {\n\t\tif err := mirrorKeyset(ctx, c.cluster, basedir, name, keyset); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tsshCredentials, err := c.FindSSHPublicKeys()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error listing SSHCredentials: %v\", err)\n\t}\n\n\tfor _, sshCredential := range sshCredentials {\n\t\tif err := mirrorSSHCredential(ctx, c.cluster, basedir, sshCredential); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// mirrorKeyset writes Keyset bundles for the certificates & privatekeys.\nfunc mirrorKeyset(ctx context.Context, cluster *kops.Cluster, basedir vfs.Path, name string, keyset *Keyset) error {\n\tif err := writeKeysetBundle(ctx, cluster, basedir.Join(\"private\"), name, keyset); err != nil {\n\t\treturn fmt.Errorf(\"writing private bundle: %v\", err)\n\t}\n\n\treturn nil","sourceCodeStart":198,"sourceCodeEnd":234,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/vfs_castore.go#L198-L234","documentation":"During MirrorTo, VFSCAStore calls FindSSHPublicKeys to enumerate stored SSH public-key credentials. If that lookup fails (VFS read error, permission denied, malformed store), the failure is wrapped as \"error listing SSHCredentials\" and the mirror aborts.","triggerScenarios":"Running kops mirror/CA-store mirroring (MirrorTo) when the source state store cannot be read for ssh/public credentials: missing IAM list permissions, transient storage errors, or a corrupted credential directory layout.","commonSituations":"Mirroring clusters between accounts/regions with read-only IAM; network blips during long mirror operations; state store migrated manually and the private/ssh layout is inconsistent.","solutions":["Re-run the mirror after confirming read access to <state>/private/ssh in the source store.","Check IAM policies for list/get on the SSH credential paths.","Verify the ssh credential files were not manually moved/deleted; restore the expected layout.","Retry on transient errors; if persistent, use kops get sshpublickey to test listing directly."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Confirm SSH public keys are listable before a mirror\nif _, err := store.FindSSHPublicKeys(); err != nil {\n\treturn fmt.Errorf(\"pre-mirror check failed: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err := store.MirrorTo(ctx, dest); err != nil {\n\tif strings.Contains(err.Error(), \"SSHCredentials\") {\n\t\treturn retryWithBackoff(func() error { return store.MirrorTo(ctx, dest) })\n\t}\n\treturn err\n}","preventionTips":["Test listing with `kops get sshpublickey` before long mirror runs.","Ensure IAM permissions cover the private/ssh tree in both source and destination.","Retry transient VFS errors; fail fast on permission errors after checking creds."],"tags":["ssh","state-store","vfs","mirror"],"backgroundTag":"state-store-unreadable","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"}