kubernetes/kubernetes · error
unable to parse csr %q: %v
Error message
unable to parse csr %q: %v
What it means
Returned by the CSR auto-approver controller's handle function when capihelper.ParseCSR fails to parse the PEM-encoded certificate signing request from csr.Spec.Request. This means the CSR's request bytes are not valid PEM or do not contain a parseable x509 CertificateRequest. The approver cannot evaluate recognition logic without a valid parsed CSR.
Source
Thrown at pkg/controller/certificates/approver/sarapprove.go:87
{
recognize: isNodeClientCert,
permission: authorization.ResourceAttributes{Group: "certificates.k8s.io", Resource: "certificatesigningrequests", Verb: "create", Subresource: "nodeclient", Version: "*"},
successMessage: "Auto approving kubelet client certificate after SubjectAccessReview.",
},
}
return recognizers
}
func (a *sarApprover) handle(ctx context.Context, csr *capi.CertificateSigningRequest) error {
if len(csr.Status.Certificate) != 0 {
return nil
}
if approved, denied := certificates.GetCertApprovalCondition(&csr.Status); approved || denied {
return nil
}
x509cr, err := capihelper.ParseCSR(csr.Spec.Request)
if err != nil {
return fmt.Errorf("unable to parse csr %q: %v", csr.Name, err)
}
tried := []string{}
for _, r := range a.recognizers {
if !r.recognize(csr, x509cr) {
continue
}
tried = append(tried, r.permission.Subresource)
approved, err := a.authorize(ctx, csr, r.permission)
if err != nil {
return err
}
if approved {
appendApprovalCondition(csr, r.successMessage)
_, err = a.client.CertificatesV1().CertificateSigningRequests().UpdateApproval(ctx, csr.Name, csr, metav1.UpdateOptions{})View on GitHub (pinned to 94c1367642)
Solutions
- Verify the CSR request bytes are valid PEM: the Spec.Request field should contain a base64-encoded PEM block starting with '-----BEGIN CERTIFICATE REQUEST-----'.
- Regenerate the CSR using openssl req -new -key <key> -out <csr> and re-encode as base64 for the API.
- Check that the PEM block type is 'CERTIFICATE REQUEST' (PKCS#10), not 'CERTIFICATE' or 'NEW CERTIFICATE REQUEST'.
- If writing a test CSR, use x509.CreateCertificateRequest and pem.EncodeToMemory to generate valid bytes.
Example fix
// before: constructing CSR with raw DER bytes
req := &capi.CertificateSigningRequest{
Spec: capi.CertificateSigningRequestSpec{
Request: derBytes, // raw DER, not PEM-encoded
},
}
// after: properly PEM-encode the CSR
pemBytes := pem.EncodeToMemory(&pem.Block{
Type: "CERTIFICATE REQUEST",
Bytes: derBytes,
})
req := &capi.CertificateSigningRequest{
Spec: capi.CertificateSigningRequestSpec{
Request: pemBytes,
},
} Defensive patterns
Strategy: validation
Validate before calling
// Validate CSR PEM block before processing
import "crypto/x509"
import "encoding/pem"
func validateCSRRequest(request []byte) error {
block, _ := pem.Decode(request)
if block == nil {
return fmt.Errorf("Spec.Request is not valid PEM")
}
if block.Type != "CERTIFICATE REQUEST" {
return fmt.Errorf("PEM block type is %q, expected CERTIFICATE REQUEST", block.Type)
}
_, err := x509.ParseCertificateRequest(block.Bytes)
if err != nil {
return fmt.Errorf("failed to parse certificate request from PEM: %w", err)
}
return nil
} Prevention
- Always PEM-encode CSR bytes using pem.EncodeToMemory with type 'CERTIFICATE REQUEST'.
- Validate CSR PEM in admission webhooks to reject malformed submissions early.
- Use openssl req -verify to check CSR integrity before submitting to the API.
- Do not pass raw DER bytes as Spec.Request — the API expects PEM.
When it happens
Trigger: A CertificateSigningRequest is submitted to the API with Spec.Request containing malformed PEM data, non-PEM data, or a valid PEM block whose DER payload is not a valid x509 CSR. The sarApprover.handle function calls capihelper.ParseCSR at line 85, which fails, and the error is wrapped at line 87.
Common situations: A kubelet or client sends a CSR with truncated or corrupted request bytes (network issues, encoding bugs). A manual CSR created with openssl that was base64-encoded incorrectly before being placed in the API object. A third-party tool that constructs CSR objects programmatically with raw bytes instead of PEM.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- PEM block type must be CERTIFICATE REQUEST
- PEM block type must be CERTIFICATE REQUEST
- PEM block type must be CERTIFICATE REQUEST
- error updating approval for csr: %v
- unable to parse certificate request: %v
AI-assisted analysis of kubernetes/kubernetes@94c1367642 (2026-08-08).
Data as JSON: /api/errors/7777f6fb2ffba6a7.
Report an issue: GitHub.