kubernetes/kops · error
keypair has no certificate
Error message
keypair has no certificate
What it means
This error is returned by promoteKeypair when the `kops promote keypair` command is asked to promote a specific keypair (by ID) whose item exists in the keyset but has no associated certificate. A keypair without a certificate cannot serve as the primary/active key because clients and the control plane verify identities via the certificate, so kOps refuses to promote it. It is a safety check to prevent making a half-created (certificate-only not yet issued) keypair the cluster's active key.
Source
Thrown at cmd/kops/promote_keypair.go:188
highestCandidateId = itemId
}
}
}
keypairID = highestCandidateId.String()
if keypairID == keyset.Primary.Id {
fmt.Fprintf(out, "No %s keypair newer than current primary %s\n", name, keypairID)
return nil
}
} else if item := keyset.Items[keypairID]; item != nil {
if item.DistrustTimestamp != nil {
return fmt.Errorf("keypair is distrusted")
}
if item.PrivateKey == nil {
return fmt.Errorf("keypair has no private key")
}
if item.Certificate == nil {
return fmt.Errorf("keypair has no certificate")
}
} else {
return fmt.Errorf("keypair not found")
}
keyset.Primary = keyset.Items[keypairID]
err = keyStore.StoreKeyset(ctx, name, keyset)
if err != nil {
return fmt.Errorf("writing keyset: %v", err)
}
fmt.Fprintf(out, "Promoted %s %s\n", name, keypairID)
return nil
}
func completePromoteKeyset(ctx context.Context, f commandutils.Factory, options *PromoteKeypairOptions, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
commandutils.ConfigureKlogForCompletion()
View on GitHub (pinned to 4c8573c808)
Solutions
- Wait for the keypair's certificate to be issued (re-run rotation/creation) and verify with `kops get keypairs <name> --type <keyset>` that the ID has a certificate, then re-run the promote.
- If keypairID was specified manually, omit it and let promoteKeypair auto-select the highest candidate (it only picks items with PrivateKey AND Certificate, excluding distrusted ones).
- If the keyset item is permanently incomplete (e.g. corrupted store state), delete the broken keypair entry (`kops delete keypair <name> <keypairID> --yes`) or re-import/reissue the keyset, then promote a valid ID.
- Inspect the keyset backing store directly (state store path for the keyset) to confirm the certificate file is present and not empty; restore it if it was lost.
Example fix
// before: promoting an incomplete keypair by explicit ID // kops promote keypair ca 3 -> "keypair has no certificate" // after: let kOps pick a fully issued candidate // kops promote keypair ca (auto-selects newest keypair with cert + private key) // or verify first: // kops get keypairs ca --type ca # confirm the target ID shows a certificate before promoting
Defensive patterns
Strategy: validation
Validate before calling
item, ok := keyset.Items[keypairID]
if ok && item.DistrustTimestamp == nil && item.PrivateKey != nil && item.Certificate != nil {
// safe to promote
}
// or CLI-side: kops get keypairs <name> and confirm the target ID has a certificate before promoting Type guard
func promotable(item *fi.KeysetItem) bool {
return item != nil && item.DistrustTimestamp == nil && item.PrivateKey != nil && item.Certificate != nil
} Prevention
- Prefer omitting keypairID so promoteKeypair auto-selects only fully issued candidates.
- Always verify with `kops get keypairs <name>` that the target ID shows a certificate before specifying it.
- Complete rotation/issuance before promoting; don't promote a keypair mid-creation.
- Automate promotes only on items that pass the promotable() checks.
When it happens
Trigger: Running `kops promote keypair <name> <keypairID>` (or calling RunPromoteKeypair with a non-empty KeypairID) where keyset.Items[keypairID] exists but item.Certificate == nil — typically a keypair created/rotated whose certificate issuance has not completed, or a keypair item that only holds a private key.
Common situations: Operators mid-rotation who grabbed a keypair ID from `kops get keypairs` too early, before the new keypair's certificate was issued; keyset entries left incomplete after a failed or interrupted rotation; manual edits or partial state in the keyset store (e.g. S3/base-store) that dropped the certificate.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- promoting keypair for %s: %v
- keypair not found
- error getting keystore: %v
- creating keypair for %s: %v
- the first keypair added to a keyset must be primary
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/9b67ce0c06e69374.
Report an issue: GitHub.