siyuan-note/siyuan · error

failed to decode certificate PEM

Error message

failed to decode certificate PEM

What it means

loadX509Certificate decodes a PEM-encoded certificate and returns this error when pem.Decode yields no block — i.e. the byte slice is not valid PEM (missing -----BEGIN CERTIFICATE----- armor, empty data, or binary content). The error prevents further x509 parsing of garbage input.

Source

Thrown at kernel/util/cert.go:245

		return nil, nil, err
	}

	cert, err = x509.ParseCertificate(certDER)
	if err != nil {
		return nil, nil, err
	}
	return certDER, cert, nil
}

func loadX509Certificate(certPath string) (*x509.Certificate, error) {
	certPEM, err := os.ReadFile(certPath)
	if err != nil {
		return nil, err
	}

	block, _ := pem.Decode(certPEM)
	if block == nil {
		return nil, fmt.Errorf("failed to decode certificate PEM")
	}
	return x509.ParseCertificate(block.Bytes)
}

// Loads the CA certificate and private key from files
func loadCA(certPath, keyPath string) (*x509.Certificate, any, error) {
	certPEM, err := os.ReadFile(certPath)
	if err != nil {
		return nil, nil, err
	}

	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 {

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Ensure the certificate file is PEM-encoded and starts with -----BEGIN CERTIFICATE-----
  2. Verify you are not passing the private key or CA file where the leaf certificate is expected
  3. Convert DER certificates to PEM: openssl x509 -inform der -in cert.der -out cert.pem

Example fix

// before: binary DER bytes handed to generateServerCert
certPEM, _ := os.ReadFile("server.der")
// after: use the PEM-encoded certificate
certPEM, _ := os.ReadFile("server.pem") // -----BEGIN CERTIFICATE----- ...
Defensive patterns

Strategy: validation

Validate before calling

const fs = require("fs");
const pem = fs.readFileSync(certPath, "utf8");
if (!pem.includes("-----BEGIN CERTIFICATE-----")) {
  throw new Error(`${certPath} is not a PEM certificate`);
}

Try / catch

cert, err := loadX509Certificate(certPEM)
if err != nil {
  return fmt.Errorf("loading server cert %s: %w", certPath, err)
}

Prevention

When it happens

Trigger: generateServerCert or the TLS cert-refresh tests passing a certificate that fails PEM decoding: an empty cert file, a key pasted where a cert is expected, a DER-encoded (binary) certificate, or text with the PEM armor stripped.

Common situations: Configuring TLS with the wrong file (private key instead of certificate); files corrupted by editors or download truncation; certificates exported in DER format instead of PEM.

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@8641553a1f (2026-09-11). Data as JSON: /api/errors/0190985df356ea6d. Report an issue: GitHub.