{"record":{"id":"48f146596a85b3a3","repo":"kubernetes/kops","slug":"error-loading-private-key-s-s-v","errorCode":null,"errorMessage":"error loading private key %s/%s: %v","messagePattern":"error loading private key (.+?)/(.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/clientset_castore.go","lineNumber":97,"sourceCode":"\t\t\tId: key.Id,\n\t\t}\n\t\tif key.DistrustTimestamp != nil {\n\t\t\tdistrustTimestamp := key.DistrustTimestamp.Time\n\t\t\tki.DistrustTimestamp = &distrustTimestamp\n\t\t}\n\t\tif len(key.PublicMaterial) != 0 {\n\t\t\tcert, err := pki.ParsePEMCertificate(key.PublicMaterial)\n\t\t\tif err != nil {\n\t\t\t\tklog.Warningf(\"key public material was %s\", key.PublicMaterial)\n\t\t\t\treturn nil, fmt.Errorf(\"error loading certificate %s/%s: %v\", name, key.Id, err)\n\t\t\t}\n\t\t\tki.Certificate = cert\n\t\t}\n\n\t\tif len(key.PrivateMaterial) != 0 {\n\t\t\tprivateKey, err := pki.ParsePEMPrivateKey(key.PrivateMaterial)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"error loading private key %s/%s: %v\", name, key.Id, err)\n\t\t\t}\n\t\t\tki.PrivateKey = privateKey\n\t\t}\n\n\t\tkeyset.Items[key.Id] = ki\n\t}\n\n\tkeyset.Primary = keyset.Items[FindPrimary(o).Id]\n\n\treturn keyset, nil\n}\n\n// loadKeyset gets the named Keyset and the format of the Keyset.\nfunc (c *ClientsetCAStore) loadKeyset(ctx context.Context, name string) (*Keyset, error) {\n\to, err := c.clientset.Keysets(c.namespace).Get(ctx, name, metav1.GetOptions{})\n\tif err != nil {\n\t\tif errors.IsNotFound(err) {\n\t\t\treturn nil, nil","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/clientset_castore.go#L79-L115","documentation":"parseKeyset decodes key.PrivateMaterial with pki.ParsePEMPrivateKey; invalid private-key bytes abort the keyset load with 'error loading private key <name>/<id>: <underlying>'. Like the certificate counterpart, one bad item prevents the entire keyset from being returned. Located at upup/pkg/fi/clientset_castore.go:97.","triggerScenarios":"A Keyset item whose PrivateMaterial is corrupt, truncated, encrypted (passphrase-protected PEM kops cannot parse), or not a PRIVATE KEY/EC PRIVATE KEY/RSA PRIVATE KEY block.","commonSituations":"Keys stored with passphrase encryption from an external tool; corrupted etcd/registry entries; keys re-encoded by another tool into an unsupported format.","solutions":["Check the stored PrivateMaterial and re-encode it as an unencrypted PEM private key (openssl pkey -in key.pem -out key-unenc.pem)","Re-issue/rotate the keypair so valid private material is stored in the Keyset","Restore the Keyset object from backup or remove the corrupt item"],"exampleFix":"// before: encrypted PEM kops cannot parse\n// -----BEGIN ENCRYPTED PRIVATE KEY-----\n// after: decrypt before storing\nopenssl pkey -in key.pem -passin pass:secret -out key-unenc.pem","handlingStrategy":"try-catch","validationCode":"if !pemHasBlock(item.PrivateMaterial, \"PRIVATE KEY\", \"RSA PRIVATE KEY\", \"EC PRIVATE KEY\") {\n\treturn fmt.Errorf(\"keyset item private material is not an unencrypted PEM private key\")\n}\nif _, err := pki.ParsePEMPrivateKey(item.PrivateMaterial); err != nil {\n\treturn fmt.Errorf(\"private key will fail to load: %w\", err)\n}","typeGuard":"func isPEMPrivateKey(b []byte) bool {\n\tblock, _ := pem.Decode(b)\n\treturn block != nil && strings.HasSuffix(block.Type, \"PRIVATE KEY\")\n}","tryCatchPattern":"keyset, err := store.FindKeyset(ctx, name)\nif err != nil {\n\tif strings.Contains(err.Error(), \"error loading private key\") {\n\t\t// rotate/re-issue the keypair for this keyset\n\t}\n\treturn err\n}","preventionTips":["Store only unencrypted PEM private keys in keysets","Decrypt externally encrypted keys before import","Test round-trip (store then parse) of key material in CI"],"tags":["go","ca","pem","private-key","deserialization"],"backgroundTag":"invalid-pem-private-key","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"}