kubernetes/kops · critical
ca key for %q was not found; cannot issue certificates
Error message
ca key for %q was not found; cannot issue certificates
What it means
IssueCert looked up the signing CA via keystore.FindPrimaryKeypair and got a result whose private key is nil. Without the CA private key, kOps cannot sign new certificates, so it refuses rather than issuing a certificate it cannot sign.
Source
Thrown at pkg/pki/issue.go:126
continue
}
if ip := net.ParseIP(san); ip != nil {
template.IPAddresses = append(template.IPAddresses, ip)
} else {
template.DNSNames = append(template.DNSNames, san)
}
}
var caPrivateKey *PrivateKey
var signer *x509.Certificate
if !template.IsCA {
var err error
caCertificate, caPrivateKey, err = keystore.FindPrimaryKeypair(ctx, request.Signer)
if err != nil {
return nil, nil, nil, err
}
if caPrivateKey == nil {
return nil, nil, nil, fmt.Errorf("ca key for %q was not found; cannot issue certificates", request.Signer)
}
if caCertificate == nil {
return nil, nil, nil, fmt.Errorf("ca certificate for %q was not found; cannot issue certificates", request.Signer)
}
signer = caCertificate.Certificate
}
privateKey := request.PrivateKey
if request.PublicKey != nil {
template.PublicKey = request.PublicKey
} else if privateKey == nil {
var err error
privateKey, err = GeneratePrivateKey()
if err != nil {
return nil, nil, nil, err
}
}
View on GitHub (pinned to 4c8573c808)
Solutions
- Recreate or restore the CA keypair in the keystore (kops toolbox pki / re-run installPKI) so the private key exists.
- Restore the missing private key backing file in the state store keyset (e.g. under <cluster>/pki/private/...).
- Issue the certificate with a signer whose keypair is complete.
Defensive patterns
Strategy: validation
Validate before calling
cert, key, err := keystore.FindPrimaryKeypair(ctx, signer)
if err != nil { return err }
if key == nil {
return fmt.Errorf("CA %s private key missing; restore keyset first", signer)
} Type guard
func caReady(kp *pki.Keypair) bool {
return kp != nil && kp.Certificate != nil && kp.PrivateKey != nil
} Try / catch
if err := installPKI(...); err != nil {
if strings.Contains(err.Error(), "ca key for") {
// recreate/restore CA keyset, then retry once
}
return err
} Prevention
- Run installPKI before any certificate issuance
- Include private keyset files in state-store backups
- Never import only the public half of a CA
When it happens
Trigger: Requesting issuance with request.Signer set to a CA name (e.g. "kubernetes-ca") whose keyset contains a certificate but no private key — e.g. the CA keypair was never created, or only the public part was imported/restored.
Common situations: Restoring a cluster state store from a backup that omitted private keys, manually importing CA certs into the keyset, or issuing certificates before installPKI created the CA.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- unknown CA %q
- ca certificate for %q was not found; cannot issue certificat
- error creating discovery CA: %w
- discovery CA creation failed
- unable to issue certificate: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/47afb9b590449ebf.
Report an issue: GitHub.