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

  1. Verify the CSR request bytes are valid PEM: the Spec.Request field should contain a base64-encoded PEM block starting with '-----BEGIN CERTIFICATE REQUEST-----'.
  2. Regenerate the CSR using openssl req -new -key <key> -out <csr> and re-encode as base64 for the API.
  3. Check that the PEM block type is 'CERTIFICATE REQUEST' (PKCS#10), not 'CERTIFICATE' or 'NEW CERTIFICATE REQUEST'.
  4. 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

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

Related errors


AI-assisted analysis of kubernetes/kubernetes@94c1367642 (2026-08-08). Data as JSON: /api/errors/7777f6fb2ffba6a7. Report an issue: GitHub.