siyuan-note/siyuan · error
failed to parse CA certificate
Error message
failed to parse CA certificate: %w
What it means
ImportCABundle accepts a CA certificate PEM and private key, validates them, and installs them into the workspace ConfDir as the TLS CA bundle. This error is returned when the PEM block decodes fine but x509.ParseCertificate rejects the DER bytes, so the certificate body is malformed or not an X.509 certificate.
Solutions
- Verify the file starts with -----BEGIN CERTIFICATE----- and re-export it with 'openssl x509 -in ca.crt -outform PEM'
- Check with 'openssl x509 -text -noout -in ca.crt' that the file parses as an X.509 certificate
- Regenerate the CA (e.g. with openssl req -x509 or the kernel's own CA generation) and re-import
Example fix
// before caCertPEM := caKeyFileContents // wrong PEM (private key) ImportCABundle(caCertPEM, caKeyPEM) // after caCertPEM := string(caCertFileContents) // -----BEGIN CERTIFICATE----- block ImportCABundle(caCertPEM, caKeyPEM)
Defensive patterns
Strategy: validation
Validate before calling
func validCertPEM(pemStr string) bool {
block, _ := pem.Decode([]byte(pemStr))
if block == nil || block.Type != "CERTIFICATE" { return false }
_, err := x509.ParseCertificate(block.Bytes)
return err == nil
} Type guard
if block == nil || block.Type != "CERTIFICATE" { return errors.New("not a certificate PEM") } Try / catch
if err := util.ImportCABundle(caCertPEM, caKeyPEM); err != nil {
if strings.Contains(err.Error(), "failed to parse CA certificate") {
// surface 'not a valid X.509 certificate' to the user
}
} Prevention
- Always export the CA as PEM ('openssl x509 -outform pem') before import
- Sanity-check with 'openssl x509 -text -noout' before pasting
- Do not paste keys, CSRs, or public keys where a certificate is expected
When it happens
Trigger: Calling ImportCABundle with caCertPEM whose first PEM block has a non-certificate type (e.g. 'PRIVATE KEY', 'CERTIFICATE REQUEST') or corrupted/truncated base64 DER payload.
Common situations: Pasting the wrong PEM file (the CA key instead of the CA cert), a certificate re-saved or truncated by a text editor, or a CSR/Public-key PEM copied from a CSR generation step.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
- 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 decode CA certificate PEM
- failed to decode CA key PEM
- failed to decode certificate PEM
- failed to generate TLS server certificate
- the provided certificate is not a CA certificate
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/6e4d265280282dd8.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/util/cert.go:323
}
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 {
return fmt.Errorf("failed to parse CA private key: %w", err)
}
caCertPath := filepath.Join(ConfDir, TLSCACertFilename)
caKeyPath := filepath.Join(ConfDir, TLSCAKeyFilename)View on GitHub (pinned to 9f775e8a12)