kubernetes/kops · error
error loading private key %s/%s: %v
Error message
error loading private key %s/%s: %v
What it means
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.
Source
Thrown at upup/pkg/fi/clientset_castore.go:97
Id: key.Id,
}
if key.DistrustTimestamp != nil {
distrustTimestamp := key.DistrustTimestamp.Time
ki.DistrustTimestamp = &distrustTimestamp
}
if len(key.PublicMaterial) != 0 {
cert, err := pki.ParsePEMCertificate(key.PublicMaterial)
if err != nil {
klog.Warningf("key public material was %s", key.PublicMaterial)
return nil, fmt.Errorf("error loading certificate %s/%s: %v", name, key.Id, err)
}
ki.Certificate = cert
}
if len(key.PrivateMaterial) != 0 {
privateKey, err := pki.ParsePEMPrivateKey(key.PrivateMaterial)
if err != nil {
return nil, fmt.Errorf("error loading private key %s/%s: %v", name, key.Id, err)
}
ki.PrivateKey = privateKey
}
keyset.Items[key.Id] = ki
}
keyset.Primary = keyset.Items[FindPrimary(o).Id]
return keyset, nil
}
// loadKeyset gets the named Keyset and the format of the Keyset.
func (c *ClientsetCAStore) loadKeyset(ctx context.Context, name string) (*Keyset, error) {
o, err := c.clientset.Keysets(c.namespace).Get(ctx, name, metav1.GetOptions{})
if err != nil {
if errors.IsNotFound(err) {
return nil, nilView on GitHub (pinned to 4c8573c808)
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
Example fix
// before: encrypted PEM kops cannot parse // -----BEGIN ENCRYPTED PRIVATE KEY----- // after: decrypt before storing openssl pkey -in key.pem -passin pass:secret -out key-unenc.pem
Defensive patterns
Strategy: try-catch
Validate before calling
if !pemHasBlock(item.PrivateMaterial, "PRIVATE KEY", "RSA PRIVATE KEY", "EC PRIVATE KEY") {
return fmt.Errorf("keyset item private material is not an unencrypted PEM private key")
}
if _, err := pki.ParsePEMPrivateKey(item.PrivateMaterial); err != nil {
return fmt.Errorf("private key will fail to load: %w", err)
} Type guard
func isPEMPrivateKey(b []byte) bool {
block, _ := pem.Decode(b)
return block != nil && strings.HasSuffix(block.Type, "PRIVATE KEY")
} Try / catch
keyset, err := store.FindKeyset(ctx, name)
if err != nil {
if strings.Contains(err.Error(), "error loading private key") {
// rotate/re-issue the keypair for this keyset
}
return err
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: Keys stored with passphrase encryption from an external tool; corrupted etcd/registry entries; keys re-encoded by another tool into an unsupported format.
Related errors
- error loading certificate %s/%s: %v
- parsing keyset %q: %w
- decoding pem public key
- unexpected key type %q
- error loading private key %q: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/48f146596a85b3a3.
Report an issue: GitHub.