{"record":{"id":"7777f6fb2ffba6a7","repo":"kubernetes/kubernetes","slug":"unable-to-parse-csr-q-v","errorCode":null,"errorMessage":"unable to parse csr %q: %v","messagePattern":"unable to parse csr %q: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/controller/certificates/approver/sarapprove.go","lineNumber":87,"sourceCode":"\t\t{\n\t\t\trecognize:      isNodeClientCert,\n\t\t\tpermission:     authorization.ResourceAttributes{Group: \"certificates.k8s.io\", Resource: \"certificatesigningrequests\", Verb: \"create\", Subresource: \"nodeclient\", Version: \"*\"},\n\t\t\tsuccessMessage: \"Auto approving kubelet client certificate after SubjectAccessReview.\",\n\t\t},\n\t}\n\treturn recognizers\n}\n\nfunc (a *sarApprover) handle(ctx context.Context, csr *capi.CertificateSigningRequest) error {\n\tif len(csr.Status.Certificate) != 0 {\n\t\treturn nil\n\t}\n\tif approved, denied := certificates.GetCertApprovalCondition(&csr.Status); approved || denied {\n\t\treturn nil\n\t}\n\tx509cr, err := capihelper.ParseCSR(csr.Spec.Request)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"unable to parse csr %q: %v\", csr.Name, err)\n\t}\n\n\ttried := []string{}\n\n\tfor _, r := range a.recognizers {\n\t\tif !r.recognize(csr, x509cr) {\n\t\t\tcontinue\n\t\t}\n\n\t\ttried = append(tried, r.permission.Subresource)\n\n\t\tapproved, err := a.authorize(ctx, csr, r.permission)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif approved {\n\t\t\tappendApprovalCondition(csr, r.successMessage)\n\t\t\t_, err = a.client.CertificatesV1().CertificateSigningRequests().UpdateApproval(ctx, csr.Name, csr, metav1.UpdateOptions{})","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/kubernetes/kubernetes/blob/94c136764292cc5fac976c0de6587daaea56410f/pkg/controller/certificates/approver/sarapprove.go#L69-L105","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: constructing CSR with raw DER bytes\nreq := &capi.CertificateSigningRequest{\n    Spec: capi.CertificateSigningRequestSpec{\n        Request: derBytes, // raw DER, not PEM-encoded\n    },\n}\n\n// after: properly PEM-encode the CSR\npemBytes := pem.EncodeToMemory(&pem.Block{\n    Type:  \"CERTIFICATE REQUEST\",\n    Bytes: derBytes,\n})\nreq := &capi.CertificateSigningRequest{\n    Spec: capi.CertificateSigningRequestSpec{\n        Request: pemBytes,\n    },\n}","handlingStrategy":"validation","validationCode":"// Validate CSR PEM block before processing\nimport \"crypto/x509\"\nimport \"encoding/pem\"\n\nfunc validateCSRRequest(request []byte) error {\n    block, _ := pem.Decode(request)\n    if block == nil {\n        return fmt.Errorf(\"Spec.Request is not valid PEM\")\n    }\n    if block.Type != \"CERTIFICATE REQUEST\" {\n        return fmt.Errorf(\"PEM block type is %q, expected CERTIFICATE REQUEST\", block.Type)\n    }\n    _, err := x509.ParseCertificateRequest(block.Bytes)\n    if err != nil {\n        return fmt.Errorf(\"failed to parse certificate request from PEM: %w\", err)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["certificates","csr","approver","x509","pem","kubernetes"],"backgroundTag":null,"analyzedSha":"94c136764292cc5fac976c0de6587daaea56410f","analyzedAt":"2026-08-08T23:58:27.554Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}