{"record":{"id":"87a5d2ae1884e34d","repo":"kubernetes/kops","slug":"writing-private-bundle-v","errorCode":null,"errorMessage":"writing private bundle: %v","messagePattern":"writing private bundle: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/vfs_castore.go","lineNumber":231,"sourceCode":"\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\n}\n\n// mirrorSSHCredential writes the SSH credential file to the mirror location\nfunc mirrorSSHCredential(ctx context.Context, cluster *kops.Cluster, basedir vfs.Path, sshCredential *kops.SSHCredential) error {\n\tid, err := sshcredentials.Fingerprint(sshCredential.Spec.PublicKey)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error fingerprinting SSH public key %q: %v\", sshCredential.Name, err)\n\t}\n\n\tp := basedir.Join(\"ssh\", \"public\", sshCredential.Name, id)\n\tacl, err := acls.GetACL(ctx, p, cluster)\n\tif err != nil {\n\t\treturn err\n\t}\n","sourceCodeStart":213,"sourceCodeEnd":249,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/vfs_castore.go#L213-L249","documentation":"mirrorKeyset writes a keyset bundle (certificates/privatekeys) into the mirror's \"private\" directory via writeKeysetBundle. Any failure in that write — serialization errors, ACL resolution failures, or VFS write errors to the destination — is wrapped as \"writing private bundle\".","triggerScenarios":"MirrorTo -> mirrorKeyset when the destination store rejects the write: destination bucket missing/readonly, GetACL failure on the mirror path, or the underlying encode (error serializing keyset) failed.","commonSituations":"Mirroring to a new bucket that has not been created or lacks write IAM; destination ACL config incompatible with the cluster's ACL rules; disk/full or throttled storage backends.","solutions":["Verify the destination VFS path exists and credentials have write permissions there.","Check the wrapped inner error to distinguish ACL failure vs serialization failure and fix accordingly.","Ensure the target cluster's ACL configuration (acls.GetACL) is valid for the destination provider.","Retry the mirror; if throttling or transient storage errors occur, back off and re-run."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Verify destination is writable before mirroring\nprobe := dest.Join(\".kops-mirror-probe\")\nif err := probe.WriteFile(context.TODO(), []byte(\"ok\"), nil); err != nil {\n\treturn fmt.Errorf(\"destination not writable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err := writeKeysetBundle(ctx, cluster, basedir, name, keyset); err != nil {\n\treturn fmt.Errorf(\"writing private bundle for %q: %w — check destination permissions and ACL config\", name, err)\n}","preventionTips":["Create and permission the destination bucket/path before the first mirror.","Verify the destination cluster ACL configuration matches the provider.","Run a dry-run mirror with a small keyset to validate the pipeline."],"tags":["mirror","keystore","vfs","write-failed"],"backgroundTag":"keyset-write-failed","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}