{"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":"exception","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/9f775e8a12daef8255556097396f9b2739078892/kernel/util/cert.go#L300-L336","documentation":"ImportCABundle imports a CA certificate and key from PEM strings supplied by the user. This error means the CA certificate string could not be decoded into a PEM block — it is empty, not PEM-formatted, or missing the CERTIFICATE header/footer.","triggerScenarios":"Calling the import CA bundle API with caCertPEM that is empty, base64-encoded-only, DER binary, or missing BEGIN/END lines; pasting a key where the cert should go.","commonSituations":"Users copying a certificate from a browser export in DER format; omitting header/footer lines when pasting; uploading the private key file into the certificate field; trailing whitespace/encoding issues from clipboard.","solutions":["Supply the certificate in valid PEM form including -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- lines","Ensure you are passing the certificate (not the key) to caCertPEM","Convert DER to PEM (openssl x509 -inform DER -in cert.der -out cert.pem) before importing","Trim surrounding whitespace/BOM and verify the string is non-empty before calling"],"exampleFix":"// before\nImportCABundle(\"MIIDdzCCAl+g...\", keyPEM) // raw DER/base64\n// after\nImportCABundle(\"-----BEGIN CERTIFICATE-----\\nMIIDdzCCAl+g...\\n-----END CERTIFICATE-----\", keyPEM)","handlingStrategy":"validation","validationCode":"const cert = caCertPEM.trim();\nif (!cert.startsWith('-----BEGIN CERTIFICATE-----') || !cert.endsWith('-----END CERTIFICATE-----')) {\n  throw new Error('caCertPEM must be PEM-encoded');\n}","typeGuard":"function isPEMCertificate(s) {\n  return typeof s === \"string\" && s.includes(\"-----BEGIN CERTIFICATE-----\");\n}","tryCatchPattern":"try {\n  await importCABundle(certPEM, keyPEM);\n} catch (e) {\n  if (e.message.includes(\"decode CA certificate PEM\")) {\n    alert(\"Certificate must be PEM format with BEGIN/END lines\");\n  }\n}","preventionTips":["Convert DER/binary certs to PEM before importing","Paste full text including BEGIN/END lines","Double-check cert vs key field placement","Trim whitespace and BOM from pasted content"],"tags":["tls","pem","certificate","import"],"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"}