{"record":{"id":"f240dadacbadbca9","repo":"siyuan-note/siyuan","slug":"the-provided-certificate-is-not-a-ca-certificate","errorCode":null,"errorMessage":"the provided certificate is not a CA certificate","messagePattern":"the provided certificate is not a CA certificate","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/util/cert.go","lineNumber":327,"sourceCode":"\t}\n\n\treturn nil\n}\n\n// ImportCABundle imports a CA certificate and private key from PEM-encoded strings.\nfunc ImportCABundle(caCertPEM, caKeyPEM string) error {\n\tcertBlock, _ := pem.Decode([]byte(caCertPEM))\n\tif certBlock == nil {\n\t\treturn fmt.Errorf(\"failed to decode CA certificate PEM\")\n\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}","sourceCodeStart":309,"sourceCodeEnd":345,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/util/cert.go#L309-L345","documentation":"Returned by ImportCABundle when the parsed certificate's IsCA flag is false. The cert parsed correctly but it is a leaf/end-entity certificate (e.g. a server TLS cert), not a CA certificate, so it cannot be installed as the local CA that signs server certs.","triggerScenarios":"Calling ImportCABundle with a server/leaf certificate (BasicConstraints CA:FALSE) instead of a CA certificate.","commonSituations":"Confusing the server TLS cert with the CA cert; importing a certificate that was issued for TLS server auth but never had CA:TRUE / KeyUsage CertSign.","solutions":["Provide the CA certificate that issued the server cert, not the server cert itself.","Confirm `openssl x509 -in ca.pem -noout -text` shows `CA:TRUE` under Basic Constraints.","If you only have a leaf cert, generate a local CA instead (GetOrCreateTLSCert) rather than importing."],"exampleFix":"// before\nImportCABundle(serverCertPEM, keyPEM) // -> not a CA certificate\n\n// after\nImportCABundle(caCertPEM, caKeyPEM) // CA:TRUE, KeyUsageCertSign","handlingStrategy":"validation","validationCode":"// Confirm IsCA before importing.\nblock, _ := pem.Decode([]byte(caCertPEM))\nif block == nil { return errors.New(\"invalid PEM\") }\ncert, err := x509.ParseCertificate(block.Bytes)\nif err != nil { return err }\nif !cert.IsCA {\n    return errors.New(\"provided cert is a leaf, not a CA; supply the issuing CA cert\")\n}\nreturn util.ImportCABundle(caCertPEM, caKeyPEM)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check `openssl x509 -in ca.pem -noout -text` shows `CA:TRUE` before importing.","Do not confuse the server TLS cert with the CA cert.","If you only have a leaf cert, let SiYuan generate its own CA via GetOrCreateTLSCert."],"tags":["tls","cert","ca","x509","crypto"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}