siyuan-note/siyuan · error
failed to decode CA key PEM
Error message
failed to decode CA key PEM
What it means
loadCA decodes the CA private key with pem.Decode and returns this error when the key bytes are not valid PEM. A decodable block is then parsed as an EC private key, so anything other than a PEM 'EC PRIVATE KEY' (or encrypted/foreign format) fails either here or in the subsequent ParseECPrivateKey.
Source
Thrown at kernel/util/cert.go:274
block, _ := pem.Decode(certPEM)
if block == nil {
return nil, nil, fmt.Errorf("failed to decode CA certificate PEM")
}
caCert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return nil, nil, err
}
keyPEM, err := os.ReadFile(keyPath)
if err != nil {
return nil, nil, err
}
block, _ = pem.Decode(keyPEM)
if block == nil {
return nil, nil, fmt.Errorf("failed to decode CA key PEM")
}
caKey, err := x509.ParseECPrivateKey(block.Bytes)
if err != nil {
return nil, nil, err
}
return caCert, caKey, nil
}
func writeCertAndKey(certPath, keyPath string, certDER []byte, privateKey *ecdsa.PrivateKey) error {
certFile, err := os.Create(certPath)
if err != nil {
return err
}
defer certFile.Close()
if err = pem.Encode(certFile, &pem.Block{Type: "CERTIFICATE", Bytes: certDER}); err != nil {View on GitHub (pinned to 8641553a1f)
Solutions
- Ensure the CA key file contains an unencrypted PEM EC private key (-----BEGIN EC PRIVATE KEY-----)
- Regenerate the CA and server certificate pair so formats match what the kernel generates
- Convert if needed: openssl ec -in key.pem -out ec-key.pem; verify with openssl ec -in ec-key.pem -check -noout
Example fix
// before: RSA PKCS#1 key saved as the CA key
caKeyPEM, _ := os.ReadFile("ca-rsa-key.pem") // -----BEGIN RSA PRIVATE KEY-----
// after: matching EC key as produced by the kernel
caKeyPEM, _ := os.ReadFile("ca.key") // -----BEGIN EC PRIVATE KEY----- Defensive patterns
Strategy: validation
Validate before calling
const fs = require("fs");
const pem = fs.readFileSync(caKeyPath, "utf8");
if (!pem.includes("-----BEGIN EC PRIVATE KEY-----")) {
throw new Error(`${caKeyPath} is not an unencrypted PEM EC private key`);
} Try / catch
caCert, caKey, err := loadCA(caCertPath, caKeyPath)
if err != nil {
log.Errorf("load CA key failed: %v", err)
return nil, err
} Prevention
- Generate CA keys as unencrypted EC keys matching the loader's expectation
- Do not convert or re-export keys to RSA/PKCS#8 formats before handing them to the kernel
- Verify with `openssl ec -in ca.key -check -noout` before use
When it happens
Trigger: GetOrCreateTLSCert or refreshCertificate loading a CA key file that is empty, holds the certificate instead of the key, contains a PKCS#1 RSA key or an encrypted PEM where an unencrypted EC key is expected, or has lost its -----BEGIN ... PRIVATE KEY----- armor.
Common situations: Manually generated CA where the key was saved in another format (RSA instead of EC, PKCS#8); key file truncated or overwritten during rotation; wrong-path config mixing up cert and key files.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to decode CA private key PEM
- failed to decode certificate PEM
- failed to decode CA certificate PEM
- failed to parse CA private key: %w
- download failed: %s
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/a4f66a66d2dcd4f1.
Report an issue: GitHub.