{"record":{"id":"ac7b8e422236ffb3","repo":"kubernetes/kops","slug":"reading-keyset-v","errorCode":null,"errorMessage":"reading keyset: %v","messagePattern":"reading keyset: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/kops/promote_keypair.go","lineNumber":159,"sourceCode":"\tif err != nil {\n\t\treturn fmt.Errorf(\"listing keysets: %v\", err)\n\t}\n\n\tfor name := range keysets {\n\t\tif rotatableKeysetFilter(name, nil) {\n\t\t\tif err := promoteKeypair(ctx, out, name, \"\", keyStore); err != nil {\n\t\t\t\treturn fmt.Errorf(\"promoting keypair for %s: %v\", name, err)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc promoteKeypair(ctx context.Context, out io.Writer, name string, keypairID string, keyStore fi.CAStore) error {\n\tkeyset, err := keyStore.FindKeyset(ctx, name)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"reading keyset: %v\", err)\n\t} else if keyset == nil {\n\t\treturn fmt.Errorf(\"keyset not found\")\n\t}\n\n\tif keypairID == \"\" {\n\t\thighestCandidateId := big.NewInt(0)\n\t\tfor id, item := range keyset.Items {\n\t\t\tif item.PrivateKey != nil && item.DistrustTimestamp == nil && item.Certificate != nil {\n\t\t\t\titemId, ok := big.NewInt(0).SetString(id, 10)\n\t\t\t\tif ok && highestCandidateId.Cmp(itemId) < 0 {\n\t\t\t\t\thighestCandidateId = itemId\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tkeypairID = highestCandidateId.String()\n\t\tif keypairID == keyset.Primary.Id {\n\t\t\tfmt.Fprintf(out, \"No %s keypair newer than current primary %s\\n\", name, keypairID)","sourceCodeStart":141,"sourceCodeEnd":177,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/cmd/kops/promote_keypair.go#L141-L177","documentation":"promoteKeypair calls keyStore.FindKeyset(ctx, name) to load the named keyset (e.g. kubernetes-ca, service-account) from the cluster's key store. If that read returns an error — backend failure, I/O error, or corrupt stored data — it is wrapped as \"reading keyset: <cause>\" and promotion aborts. The keyset is never modified in this case.","triggerScenarios":"Any error returned by fi.CAStore.FindKeyset during `kops promote keypair <keyset>` or `promote keypair all`: unreachable/permission-denied state store, network timeout, malformed/corrupt keyset file in the state store, or vfs backend failure.","commonSituations":"Wrong or expired cloud credentials; --state pointing at a store the user cannot read; S3/GCS throttling or outage; a keyset JSON/object corrupted by a partial write or manual edit.","solutions":["Inspect the wrapped cause after \"reading keyset: \" to identify the backend error.","Verify state-store credentials and permissions (cloud CLI auth, KOPS_STATE_STORE/--state value).","Retry after transient network/backend issues clear.","If the stored keyset object is corrupt, restore it from the state store's versioning/backup or reissue the keypair with `kops replace`/`kops create keypair` before promoting."],"exampleFix":"// before: failing due to bad state store\nkops promote keypair kubernetes-ca --name c.example.com\n// error: reading keyset: unable to read s3://bucket/... \n// after: pass/verify explicit state store and credentials\nexport KOPS_STATE_STORE=s3://my-state-store\naws s3 ls $KOPS_STATE_STORE/cluster/c.example.com/pki/  # sanity-check access\nkops promote keypair kubernetes-ca --name c.example.com","handlingStrategy":"retry","validationCode":"// pre-flight: confirm the keyset is readable via kops before mutating\nkops get keypairs \"$KEYSET\" --name \"$CLUSTER\" --state \"$KOPS_STATE_STORE\" || \\\n  { echo \"keyset $KEYSET unreadable; check credentials/state store\"; exit 1; }","typeGuard":null,"tryCatchPattern":"for attempt in 1 2 3; do\n  kops promote keypair \"$KEYSET\" --name \"$CLUSTER\" --state \"$KOPS_STATE_STORE\" && break\n  rc=$?\n  echo \"attempt $attempt failed (reading keyset); retrying in 10s\"\n  sleep 10\ndone\n[ \"$rc\" -eq 0 ] || echo \"persistent keyset read failure — check state-store permissions/health\"","preventionTips":["Keep cloud credentials fresh (aws sts get-caller-identity / gcloud auth list before maintenance).","Pin KOPS_STATE_STORE per cluster to avoid pointing at the wrong bucket.","Never hand-edit keyset objects in the state store.","Enable state-store versioning so partially written/corrupt keysets can be reverted."],"tags":["keystore","state-store","io","cli"],"backgroundTag":"state-store-read-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"}