siyuan-note/siyuan · error
failed to parse CA private key: %w
Error message
failed to parse CA private key: %w
What it means
Returned by ImportCABundle when x509.ParseECPrivateKey fails on the decoded key block bytes. ImportCABundle only accepts an EC private key (SEC1, PEM type `EC PRIVATE KEY`). RSA keys, PKCS#8-wrapped keys, or malformed EC keys all fail here.
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 251596fc0d)
Solutions
- Generate/provide an EC (P-256) private key in SEC1 PEM form.
- Convert RSA or PKCS#8 keys: `openssl ecparam -name prime256v1 -genkey -noout -out ca.key` for a fresh EC key, or `openssl pkcs8 -topk8 -nocrypt -in pkcs8.pem -out sec1.pem` then ensure SEC1 EC encoding.
- Match the key to the cert: the public key in caCertPEM must correspond to caKeyPEM.
Example fix
// before: RSA key rejected by ParseECPrivateKey ImportCABundle(certPEM, rsaKeyPEM) // -> failed to parse CA private key // after: generate an EC P-256 key pair and use that // openssl ecparam -name prime256v1 -genkey -noout -out ca.key ImportCABundle(certPEM, ecSec1KeyPEM)
Defensive patterns
Strategy: try-catch
Try / catch
if err := util.ImportCABundle(certPEM, keyPEM); err != nil {
if strings.Contains(err.Error(), "failed to parse CA private key") {
// Only SEC1 EC keys are accepted; RSA / PKCS#8 / malformed all fail here
return fmt.Errorf("%v; supply a P-256 EC key in SEC1 PEM form", err)
}
return err
} Prevention
- Generate the CA key as EC P-256: `openssl ecparam -name prime256v1 -genkey -noout -out ca.key`.
- Convert PKCS#8 EC keys to SEC1 before importing.
- Match the key to the cert's public key before importing.
When it happens
Trigger: Calling ImportCABundle with a private key that is not a SEC1 EC private key — e.g. an RSA key (`-----BEGIN RSA PRIVATE KEY-----`), a PKCS#8 `PRIVATE KEY`, or a corrupted EC key.
Common situations: Trying to reuse an existing RSA CA key with SiYuan's local TLS (which is ECDSA/P-256 based); supplying a PKCS#8-encoded EC key without converting to SEC1.
Understand the failure class
- 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 parse CA certificate: %w
- the provided certificate is not a CA certificate
- failed to write CA private key: %w
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/db8b58468d19cd74.
Report an issue: GitHub.