{"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":"exception","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/9f775e8a12daef8255556097396f9b2739078892/kernel/util/cert.go#L319-L355","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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'"],"exampleFix":"// before\n// openssl genrsa -out ca.key 2048  -> RSA key, rejected\n// after\n// openssl ecparam -genkey -name prime256v1 -out ca.key  -> EC key, accepted","handlingStrategy":"validation","validationCode":"func isECKeyPEM(pemStr string) bool {\n    block, _ := pem.Decode([]byte(pemStr))\n    if block == nil { return false }\n    _, err := x509.ParseECPrivateKey(block.Bytes)\n    return err == nil\n}","typeGuard":"if _, err := x509.ParseECPrivateKey(block.Bytes); err != nil { return errors.New(\"not an EC private key\") }","tryCatchPattern":"if err := util.ImportCABundle(caCertPEM, caKeyPEM); err != nil {\n    if strings.Contains(err.Error(), \"failed to parse CA private key\") {\n        // suggest converting the key to SEC1 EC PEM\n    }\n}","preventionTips":["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"],"tags":["tls","private-key","ecdsa","pem"],"backgroundTag":"invalid-argument-format","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}