{"record":{"id":"bda7bccf34ff81dc","repo":"siyuan-note/siyuan","slug":"failed-to-decode-ca-certificate-pem","errorCode":null,"errorMessage":"failed to decode CA certificate PEM","messagePattern":"failed to decode CA certificate PEM","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/util/cert.go","lineNumber":318,"sourceCode":"\tdefer keyFile.Close()\n\n\tkeyDER, err := x509.MarshalECPrivateKey(privateKey)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif err = pem.Encode(keyFile, &pem.Block{Type: \"EC PRIVATE KEY\", Bytes: keyDER}); err != nil {\n\t\treturn err\n\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 {","sourceCodeStart":300,"sourceCodeEnd":336,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/util/cert.go#L300-L336","documentation":"Returned by ImportCABundle in kernel/util/cert.go when pem.Decode on the caCertPEM string returns a nil block — the input is not valid PEM (missing -----BEGIN/END----- markers, wrong label, empty, or corrupted). This is the first validation step before parsing the certificate.","triggerScenarios":"Calling util.ImportCABundle(caCertPEM, caKeyPEM) with a caCertPEM that pem.Decode cannot parse. ImportCABundle is the entry point for supplying a custom local CA for TLS.","commonSituations":"Pasting only the base64 body without the PEM headers; supplying a DER (binary) cert instead of PEM; trailing/leading whitespace or copy-paste truncation; wrong PEM type label.","solutions":["Ensure caCertPEM is a full PEM bundle including `-----BEGIN CERTIFICATE-----` and `-----END CERTIFICATE-----` lines.","If you have a DER cert, convert it first: `openssl x509 -in ca.der -inform DER -out ca.pem -outform PEM`.","Validate the PEM with `openssl x509 -in ca.pem -noout -text` before importing."],"exampleFix":"// before\nImportCABundle(derBase64Only, keyPEM) // -> failed to decode CA certificate PEM\n\n// after\nImportCABundle(\"-----BEGIN CERTIFICATE-----\\n\" + encodedPEM + \"\\n-----END CERTIFICATE-----\\n\", keyPEM)","handlingStrategy":"validation","validationCode":"// Confirm the PEM decodes before importing.\nif block, _ := pem.Decode([]byte(caCertPEM)); block == nil {\n    return fmt.Errorf(\"ca cert is not valid PEM; include BEGIN/END CERTIFICATE markers\")\n}\nreturn util.ImportCABundle(caCertPEM, caKeyPEM)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always include full PEM headers and footers when passing cert material.","Validate with `openssl x509 -in ca.pem -noout -text` before importing.","Convert DER to PEM explicitly rather than relying on the importer."],"tags":["tls","cert","pem","ca","crypto"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}