{"record":{"id":"db8b58468d19cd74","repo":"siyuan-note/siyuan","slug":"failed-to-parse-ca-private-key-w","errorCode":null,"errorMessage":"failed to parse CA private key: %w","messagePattern":"failed to parse CA private key: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/util/cert.go","lineNumber":337,"sourceCode":"\t}\n\n\tcaCert, err := x509.ParseCertificate(certBlock.Bytes)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to parse CA certificate: %w\", err)\n\t}\n\n\tif !caCert.IsCA {\n\t\treturn fmt.Errorf(\"the provided certificate is not a CA certificate\")\n\t}\n\n\tkeyBlock, _ := pem.Decode([]byte(caKeyPEM))\n\tif keyBlock == nil {\n\t\treturn fmt.Errorf(\"failed to decode CA private key PEM\")\n\t}\n\n\t_, err = x509.ParseECPrivateKey(keyBlock.Bytes)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to parse CA private key: %w\", err)\n\t}\n\n\tcaCertPath := filepath.Join(ConfDir, TLSCACertFilename)\n\tcaKeyPath := filepath.Join(ConfDir, TLSCAKeyFilename)\n\n\tif err := os.WriteFile(caCertPath, []byte(caCertPEM), 0644); err != nil {\n\t\treturn fmt.Errorf(\"failed to write CA certificate: %w\", err)\n\t}\n\n\tif err := os.WriteFile(caKeyPath, []byte(caKeyPEM), 0600); err != nil {\n\t\treturn fmt.Errorf(\"failed to write CA private key: %w\", err)\n\t}\n\n\tcertPath := filepath.Join(ConfDir, TLSCertFilename)\n\tkeyPath := filepath.Join(ConfDir, TLSKeyFilename)\n\n\tif gulu.File.IsExist(certPath) {\n\t\tos.Remove(certPath)","sourceCodeStart":319,"sourceCodeEnd":355,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/util/cert.go#L319-L355","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: RSA key rejected by ParseECPrivateKey\nImportCABundle(certPEM, rsaKeyPEM) // -> failed to parse CA private key\n\n// after: generate an EC P-256 key pair and use that\n// openssl ecparam -name prime256v1 -genkey -noout -out ca.key\nImportCABundle(certPEM, ecSec1KeyPEM)","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := util.ImportCABundle(certPEM, keyPEM); err != nil {\n    if strings.Contains(err.Error(), \"failed to parse CA private key\") {\n        // Only SEC1 EC keys are accepted; RSA / PKCS#8 / malformed all fail here\n        return fmt.Errorf(\"%v; supply a P-256 EC key in SEC1 PEM form\", err)\n    }\n    return err\n}","preventionTips":["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."],"tags":["tls","key","ecdsa","ca","crypto"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}