siyuan-note/siyuan · error
failed to decode CA private key PEM
Error message
failed to decode CA private key PEM
What it means
After validating the CA certificate, ImportCABundle PEM-decodes the supplied private key. If pem.Decode returns no block, the key material is not valid PEM at all (no BEGIN/END delimiters or only whitespace/garbage), so the import fails before any key parsing.
Solutions
- Re-export the key in PEM form: 'openssl ec -in ca.key -out ca.key.pem'
- Ensure the text contains the full -----BEGIN ... PRIVATE KEY----- / -----END ... PRIVATE KEY----- block including newlines
- Check that you are passing the key file's contents, not the certificate file's, to ImportCABundle
Example fix
// before caKeyPEM := "MHcCAQEEI..." // raw base64, no PEM armor // after caKeyPEM := "-----BEGIN EC PRIVATE KEY-----\n...\n-----END EC PRIVATE KEY-----\n"
Defensive patterns
Strategy: validation
Validate before calling
func validKeyPEM(pemStr string) bool {
block, _ := pem.Decode([]byte(pemStr))
return block != nil && strings.Contains(block.Type, "PRIVATE KEY")
} Type guard
if block == nil || !strings.Contains(block.Type, "PRIVATE KEY") { return errors.New("not a private key PEM") } Try / catch
if err := util.ImportCABundle(caCertPEM, caKeyPEM); err != nil {
if strings.Contains(err.Error(), "failed to decode CA private key PEM") {
// tell user the key text lacks PEM armor
}
} Prevention
- Always copy the whole PEM block including BEGIN/END lines and newlines
- Never strip PEM armor or paste raw base64/DER key bytes
- Double-check you pasted the key file, not the certificate file
When it happens
Trigger: Passing an empty string, a DER-encoded binary key, or text with the PEM headers stripped/renamed as caKeyPEM to ImportCABundle.
Common situations: Pasting the key from a 'openssl ec -outform DER' output, copying only the base64 body without the -----BEGIN EC PRIVATE KEY----- wrapper, or accidentally pasting the certificate again instead of the key.
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.
- 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 private key
- failed to decode CA certificate PEM
- failed to decode CA key PEM
- failed to decode certificate PEM
- failed to parse CA certificate
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/224638877fc94350.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/util/cert.go:332
// 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)
if err := os.WriteFile(caCertPath, []byte(caCertPEM), 0644); err != nil {
return fmt.Errorf("failed to write CA certificate: %w", err)
}
if err := os.WriteFile(caKeyPath, []byte(caKeyPEM), 0600); err != nil {
return fmt.Errorf("failed to write CA private key: %w", err)
}
View on GitHub (pinned to 9f775e8a12)