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
- Import the CA certificate (the one that signed your server cert), not the server certificate itself
- If you only have a leaf cert, generate a proper CA first (openssl req -x509 -new ...) and issue a server cert from it
- 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
- Keep CA and server certificates in clearly named separate files (ca.crt vs server.crt)
- Check 'CA:TRUE' in Basic Constraints before importing
- Generate the CA with a tool that sets BasicConstraints CA:TRUE by default
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.
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- failed to generate TLS server certificate
- failed to load CA certificates
- failed to parse CA certificate
- failed to decode CA certificate PEM
- failed to decode CA key PEM
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)