siyuan-note/siyuan · error
failed to parse CA private key
Error message
failed to parse CA private key: %w
What it means
The CA private key PEM decoded successfully, but x509.ParseECPrivateKey failed, meaning the DER payload inside the PEM block is not an EC private key. ImportCABundle only supports EC keys for the CA, matching how it generates the CA internally.
Solutions
- Re-export the key as SEC1 EC PEM: 'openssl ec -in ca.key -outform pem -out ca.ec.key'
- Generate the CA key with an EC curve, e.g. 'openssl ecparam -genkey -name prime256v1'
- Check the PEM header — it must read -----BEGIN EC PRIVATE KEY-----; convert PKCS#8 EC keys with 'openssl ec -in pkcs8.key'
Example fix
// before // openssl genrsa -out ca.key 2048 -> RSA key, rejected // after // openssl ecparam -genkey -name prime256v1 -out ca.key -> EC key, accepted
Defensive patterns
Strategy: validation
Validate before calling
func isECKeyPEM(pemStr string) bool {
block, _ := pem.Decode([]byte(pemStr))
if block == nil { return false }
_, err := x509.ParseECPrivateKey(block.Bytes)
return err == nil
} Type guard
if _, err := x509.ParseECPrivateKey(block.Bytes); err != nil { return errors.New("not an EC private key") } Try / catch
if err := util.ImportCABundle(caCertPEM, caKeyPEM); err != nil {
if strings.Contains(err.Error(), "failed to parse CA private key") {
// suggest converting the key to SEC1 EC PEM
}
} Prevention
- Generate the CA key with 'openssl ecparam -genkey' (EC), not genrsa
- Convert PKCS#8 EC keys to SEC1 form with 'openssl ec' before import
- Match the key to the certificate's algorithm
When it happens
Trigger: Importing an RSA or PKCS#8/PKCS#1 key (-----BEGIN RSA PRIVATE KEY----- or -----BEGIN PRIVATE KEY-----), or a key whose DER bytes were corrupted, as caKeyPEM to ImportCABundle.
Common situations: CA generated with 'openssl genrsa' or 'openssl genpkey' defaults instead of EC; keys converted between formats losing the EC-specific ASN.1 structure; mismatched cert/key pair files.
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 decode CA private key PEM
- 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/db8b58468d19cd74.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/util/cert.go:337
}
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)
}
certPath := filepath.Join(ConfDir, TLSCertFilename)
keyPath := filepath.Join(ConfDir, TLSKeyFilename)
if gulu.File.IsExist(certPath) {
os.Remove(certPath)View on GitHub (pinned to 9f775e8a12)