siyuan-note/siyuan · error

failed to parse CA private key

Error message

failed to parse CA private key: %w

What it means

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.

Solutions

  1. Re-export the key as SEC1 EC PEM: 'openssl ec -in ca.key -outform pem -out ca.ec.key'
  2. Generate the CA key with an EC curve, e.g. 'openssl ecparam -genkey -name prime256v1'
  3. Check the PEM header — it must read -----BEGIN EC PRIVATE KEY-----; convert PKCS#8 EC keys with 'openssl ec -in pkcs8.key'

Example fix

// before
// openssl genrsa -out ca.key 2048  -> RSA key, rejected
// after
// openssl ecparam -genkey -name prime256v1 -out ca.key  -> EC key, accepted
Defensive patterns

Strategy: validation

Validate before calling

func isECKeyPEM(pemStr string) bool {
    block, _ := pem.Decode([]byte(pemStr))
    if block == nil { return false }
    _, err := x509.ParseECPrivateKey(block.Bytes)
    return err == nil
}

Type guard

if _, err := x509.ParseECPrivateKey(block.Bytes); err != nil { return errors.New("not an EC private key") }

Try / catch

if err := util.ImportCABundle(caCertPEM, caKeyPEM); err != nil {
    if strings.Contains(err.Error(), "failed to parse CA private key") {
        // suggest converting the key to SEC1 EC PEM
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

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.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/db8b58468d19cd74. Report an issue: GitHub.

Appendix: source

Thrown at kernel/util/cert.go:337

	}

	caCert, err := x509.ParseCertificate(certBlock.Bytes)
	if err != nil {
		return fmt.Errorf("failed to parse CA certificate: %w", err)
	}

	if !caCert.IsCA {
		return fmt.Errorf("the provided certificate is not a CA certificate")
	}

	keyBlock, _ := pem.Decode([]byte(caKeyPEM))
	if keyBlock == nil {
		return fmt.Errorf("failed to decode CA private key PEM")
	}

	_, err = x509.ParseECPrivateKey(keyBlock.Bytes)
	if err != nil {
		return fmt.Errorf("failed to parse CA private key: %w", err)
	}

	caCertPath := filepath.Join(ConfDir, TLSCACertFilename)
	caKeyPath := filepath.Join(ConfDir, TLSCAKeyFilename)

	if err := os.WriteFile(caCertPath, []byte(caCertPEM), 0644); err != nil {
		return fmt.Errorf("failed to write CA certificate: %w", err)
	}

	if err := os.WriteFile(caKeyPath, []byte(caKeyPEM), 0600); err != nil {
		return fmt.Errorf("failed to write CA private key: %w", err)
	}

	certPath := filepath.Join(ConfDir, TLSCertFilename)
	keyPath := filepath.Join(ConfDir, TLSKeyFilename)

	if gulu.File.IsExist(certPath) {
		os.Remove(certPath)

View on GitHub (pinned to 9f775e8a12)