kubernetes/kops · error
decoding pem public key
Error message
decoding pem public key
What it means
issueCert receives a PEM-encoded public key from the bootstrap request. This error is thrown when pem.Decode cannot parse any PEM block from the submitted key material, i.e. the payload is not valid PEM.
Source
Thrown at cmd/kops-controller/pkg/server/server.go:293
cert, err := s.issueCert(ctx, name, pubKey, id, validHours, req.KeypairIDs)
if err != nil {
klog.Infof("bootstrap %s cert %q issue err: %v", r.RemoteAddr, name, err)
w.WriteHeader(http.StatusBadRequest)
_, _ = fmt.Fprintf(w, "failed to issue %q: %v", name, err)
return
}
resp.Certs[name] = cert
}
w.Header().Set("Content-Type", "application/json")
_ = json.NewEncoder(w).Encode(resp)
klog.Infof("bootstrap %s (req.includeNodeConfig: %t, req.certs.#: %d, req.keypairs.#: %d) success", r.RemoteAddr, req.IncludeNodeConfig, len(req.Certs), len(req.KeypairIDs))
}
func (s *Server) issueCert(ctx context.Context, name string, pubKey string, id *bootstrap.VerifyResult, validHours uint32, keypairIDs map[string]string) (string, error) {
block, _ := pem.Decode([]byte(pubKey))
if block == nil {
return "", fmt.Errorf("decoding pem public key")
}
if block.Type != "RSA PUBLIC KEY" {
return "", fmt.Errorf("unexpected key type %q", block.Type)
}
key, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return "", fmt.Errorf("parsing key: %v", err)
}
issueReq := &pki.IssueCertRequest{
Signer: fi.CertificateIDCA,
Type: "client",
PublicKey: key,
Validity: time.Hour * time.Duration(validHours),
}
if !s.certNames.Has(name) {
return "", fmt.Errorf("key name not enabled")View on GitHub (pinned to 4c8573c808)
Solutions
- Log the offending request source and regenerate the key on the node
- Confirm nodeup and kops-controller versions match
- Ensure the client sends the PEM text (with BEGIN/END headers) not raw DER
- Check any proxies/mutating layers for truncation
Example fix
// before
payload["publicKey"] = string(derBytes)
// after
payload["publicKey"] = string(pem.EncodeToMemory(&pem.Block{Type: "RSA PUBLIC KEY", Bytes: derBytes})) Defensive patterns
Strategy: validation
Validate before calling
if !strings.HasPrefix(pubKey, "-----BEGIN ") {
return fmt.Errorf("public key is not PEM-encoded")
} Type guard
func isPEMBlock(s string) bool {
b, _ := pem.Decode([]byte(s))
return b != nil
} Try / catch
block, _ := pem.Decode([]byte(pubKey))
if block == nil {
return "", fmt.Errorf("decoding pem public key")
} Prevention
- Always PEM-encode keys before sending bootstrap requests
- Verify key bytes are not truncated by HTTP middleware
- Keep nodeup and kops-controller in lockstep versions
When it happens
Trigger: A bootstrap client posts a cert request whose pubKey field is empty, base64-corrupted, or otherwise not PEM-encoded, so pem.Decode returns block == nil.
Common situations: Node-side nodeup version mismatch producing non-PEM key format; key truncated or double-encoded in transit; malicious/garbage requests against the bootstrap endpoint.
Related errors
- unexpected key type %q
- parsing key: %v
- no keypairID for %q
- building nodeConfig for instanceGroup: %w
- error loading secret %q: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/4529add8193be602.
Report an issue: GitHub.