{"record":{"id":"0ada3287e4dae46c","repo":"kubernetes/kops","slug":"writing-keyset-v","errorCode":null,"errorMessage":"writing keyset: %v","messagePattern":"writing keyset: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/kops/promote_keypair.go","lineNumber":197,"sourceCode":"\t\t}\n\t} else if item := keyset.Items[keypairID]; item != nil {\n\t\tif item.DistrustTimestamp != nil {\n\t\t\treturn fmt.Errorf(\"keypair is distrusted\")\n\t\t}\n\t\tif item.PrivateKey == nil {\n\t\t\treturn fmt.Errorf(\"keypair has no private key\")\n\t\t}\n\t\tif item.Certificate == nil {\n\t\t\treturn fmt.Errorf(\"keypair has no certificate\")\n\t\t}\n\t} else {\n\t\treturn fmt.Errorf(\"keypair not found\")\n\t}\n\n\tkeyset.Primary = keyset.Items[keypairID]\n\terr = keyStore.StoreKeyset(ctx, name, keyset)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"writing keyset: %v\", err)\n\t}\n\n\tfmt.Fprintf(out, \"Promoted %s %s\\n\", name, keypairID)\n\treturn nil\n}\n\nfunc completePromoteKeyset(ctx context.Context, f commandutils.Factory, options *PromoteKeypairOptions, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {\n\tcommandutils.ConfigureKlogForCompletion()\n\n\tcluster, clientSet, completions, directive := GetClusterForCompletion(ctx, f, nil)\n\tif cluster == nil {\n\t\treturn completions, directive\n\t}\n\n\tkeyset, _, completions, directive := completeKeyset(ctx, cluster, clientSet, args, rotatableKeysetFilter)\n\tif keyset == nil {\n\t\treturn completions, directive\n\t}","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/cmd/kops/promote_keypair.go#L179-L215","documentation":"This error wraps a failure from keyStore.StoreKeyset when promoteKeypair tries to persist the keyset after updating its Primary field. After selecting the new primary kOps must write the modified keyset back to the backing store (e.g. S3, GCS, file, or the key store backend); if that write fails (permissions, connectivity, locking, serialization) the promote is aborted with this wrapped message. The cluster's keyset is left unchanged, since the write is atomic from the caller's perspective.","triggerScenarios":"`kops promote keypair` reaching the StoreKeyset call — i.e. the keypair was valid and selected — but the underlying write fails: no write permission on the state store bucket/prefix, network failure to the cloud object store, state store read-only or versioned/locked, or backend serialization error.","commonSituations":"AWS credentials lacking s3:PutObject on the state bucket; S3 bucket with Object Lock / deny policy or KMS key unavailable; offline or firewalled CI runner; state store migration (path changed, wrong --state flag pointing to a read-only replica); concurrent kOps runs conflicting on the same keyset.","solutions":["Read the wrapped %v detail to identify the backend failure, then fix it — most commonly IAM permissions on the state store bucket (e.g. s3:PutObject) or restoring network access to it.","Verify the --state store location is correct and writable; retry `kops promote keypair` after the backend is available.","Check for versioning/object-lock or KMS key issues on the bucket that could reject the PUT, and adjust the policy or credentials.","If using kops-controller-based key stores or etcd-backed stores, verify that backend's connectivity and credentials; then re-run the promote (the operation is safe to retry since nothing was written)."],"exampleFix":"// before: promote fails on write\n// kops promote keypair ca 3\n// -> writing keyset: error storing keyset \"ca\": AccessDenied ...\n// after: grant write access to the state store, then retry\n// aws s3api put-bucket-policy ... (allow s3:PutObject for the kops user)\n// kops promote keypair ca 3\n// -> Promoted ca 3","handlingStrategy":"retry","validationCode":"// Check state store writability first, e.g. for S3:\n// aws s3 cp /dev/stdin s3://<state-bucket>/test-write --content-type text/plain && aws s3 rm s3://<state-bucket>/test-write","typeGuard":null,"tryCatchPattern":"err := keyStore.StoreKeyset(ctx, name, keyset)\nif err != nil {\n    var retryable bool\n    // inspect wrapped backend error (network/timeout/throttle => retry; AccessDenied => fix IAM)\n    if isNetworkOrThrottleError(err) {\n        retryable = true\n    }\n    return fmt.Errorf(\"writing keyset: %v (retryable=%v)\", err, retryable)\n}","preventionTips":["Grant the operator's credentials write access to the state store (e.g. s3:PutObject) before rotating keys.","Run promotes from a machine with reliable connectivity to the cloud object store; avoid flaky CI runners for key operations.","Watch for bucket versioning/object-lock/KMS policies that can reject writes; test with a harmless write first.","Avoid concurrent kOps mutations on the same keyset; the write failure is safe to retry after fixing the cause."],"tags":["keystore","state-store","persistence","aws","permissions"],"backgroundTag":"state-store-write-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"}