siyuan-note/siyuan · error

the provided certificate is not a CA certificate

Error message

the provided certificate is not a CA certificate

What it means

ImportCABundle requires that the supplied certificate actually be a Certificate Authority (CA). After parsing succeeds, it checks caCert.IsCA; if the BasicConstraints CA flag is false the import is rejected because the cert cannot sign the server/leaf certificates the TLS layer will issue or verify.

Solutions

  1. Import the CA certificate (the one that signed your server cert), not the server certificate itself
  2. If you only have a leaf cert, generate a proper CA first (openssl req -x509 -new ...) and issue a server cert from it
  3. Confirm CA status with 'openssl x509 -text -noout -in ca.crt' — look for 'CA:TRUE' under X509v3 Basic Constraints

Example fix

// before
ImportCABundle(serverCertPEM, caKeyPEM) // leaf cert rejected
// after
ImportCABundle(caCertPEM, caKeyPEM) // cert with CA:TRUE BasicConstraints
Defensive patterns

Strategy: validation

Validate before calling

func isCACert(pemStr string) bool {
    block, _ := pem.Decode([]byte(pemStr))
    if block == nil { return false }
    cert, err := x509.ParseCertificate(block.Bytes)
    return err == nil && cert.IsCA
}

Type guard

if cert, err := x509.ParseCertificate(block.Bytes); err != nil || !cert.IsCA { return errors.New("not a CA certificate") }

Try / catch

if err := util.ImportCABundle(caCertPEM, caKeyPEM); err != nil {
    if strings.Contains(err.Error(), "not a CA certificate") {
        // prompt user to select the CA cert, not the server cert
    }
}

Prevention

When it happens

Trigger: Importing a leaf/server or client certificate PEM instead of the CA certificate; the PEM parses as valid X.509 but its BasicConstraints extension does not assert CA:TRUE.

Common situations: Copying the server cert (cert.pem) rather than the CA cert when setting up HTTPS for the workspace; using a self-signed end-entity certificate as the trust anchor.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at kernel/util/cert.go:327

	}

	return nil
}

// ImportCABundle imports a CA certificate and private key from PEM-encoded strings.
func ImportCABundle(caCertPEM, caKeyPEM string) error {
	certBlock, _ := pem.Decode([]byte(caCertPEM))
	if certBlock == nil {
		return fmt.Errorf("failed to decode CA certificate PEM")
	}

	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)
	}

View on GitHub (pinned to 9f775e8a12)