siyuan-note/siyuan · error
failed to decode CA certificate PEM
Error message
failed to decode CA certificate PEM
What it means
Returned by ImportCABundle in kernel/util/cert.go when pem.Decode on the caCertPEM string returns a nil block — the input is not valid PEM (missing -----BEGIN/END----- markers, wrong label, empty, or corrupted). This is the first validation step before parsing the certificate.
Source
Thrown at kernel/util/cert.go:318
defer keyFile.Close()
keyDER, err := x509.MarshalECPrivateKey(privateKey)
if err != nil {
return err
}
if err = pem.Encode(keyFile, &pem.Block{Type: "EC PRIVATE KEY", Bytes: keyDER}); err != nil {
return err
}
return nil
}
// ImportCABundle imports a CA certificate and private key from PEM-encoded strings.
func ImportCABundle(caCertPEM, caKeyPEM string) error {
certBlock, _ := pem.Decode([]byte(caCertPEM))
if certBlock == nil {
return fmt.Errorf("failed to decode CA certificate PEM")
}
caCert, err := x509.ParseCertificate(certBlock.Bytes)
if err != nil {
return fmt.Errorf("failed to parse CA certificate: %w", err)
}
if !caCert.IsCA {
return fmt.Errorf("the provided certificate is not a CA certificate")
}
keyBlock, _ := pem.Decode([]byte(caKeyPEM))
if keyBlock == nil {
return fmt.Errorf("failed to decode CA private key PEM")
}
_, err = x509.ParseECPrivateKey(keyBlock.Bytes)
if err != nil {View on GitHub (pinned to 251596fc0d)
Solutions
- Ensure caCertPEM is a full PEM bundle including `-----BEGIN CERTIFICATE-----` and `-----END CERTIFICATE-----` lines.
- If you have a DER cert, convert it first: `openssl x509 -in ca.der -inform DER -out ca.pem -outform PEM`.
- Validate the PEM with `openssl x509 -in ca.pem -noout -text` before importing.
Example fix
// before
ImportCABundle(derBase64Only, keyPEM) // -> failed to decode CA certificate PEM
// after
ImportCABundle("-----BEGIN CERTIFICATE-----\n" + encodedPEM + "\n-----END CERTIFICATE-----\n", keyPEM) Defensive patterns
Strategy: validation
Validate before calling
// Confirm the PEM decodes before importing.
if block, _ := pem.Decode([]byte(caCertPEM)); block == nil {
return fmt.Errorf("ca cert is not valid PEM; include BEGIN/END CERTIFICATE markers")
}
return util.ImportCABundle(caCertPEM, caKeyPEM) Prevention
- Always include full PEM headers and footers when passing cert material.
- Validate with `openssl x509 -in ca.pem -noout -text` before importing.
- Convert DER to PEM explicitly rather than relying on the importer.
When it happens
Trigger: Calling util.ImportCABundle(caCertPEM, caKeyPEM) with a caCertPEM that pem.Decode cannot parse. ImportCABundle is the entry point for supplying a custom local CA for TLS.
Common situations: Pasting only the base64 body without the PEM headers; supplying a DER (binary) cert instead of PEM; trailing/leading whitespace or copy-paste truncation; wrong PEM type label.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to parse CA certificate: %w
- the provided certificate is not a CA certificate
- failed to decode CA private key PEM
- failed to parse CA private key: %w
- failed to write CA certificate: %w
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/bda7bccf34ff81dc.
Report an issue: GitHub.