crowdsecurity/crowdsec · error
failed to append CA cert file %s: %w
Error message
failed to append CA cert file %s: %w
What it means
After successfully reading the CA file, ConnectionString calls AppendCertsFromPEM on the x509 pool. If the content is not valid PEM (or contains no usable certificates), it returns false and the code wraps the (nil) read error as 'failed to append CA cert file %s: %w'. Note: the wrapped err here is nil, so the underlying cause is the file content itself.
Source
Thrown at pkg/csconfig/database.go:176
} else {
connString = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", d.User, d.Password, d.Host, d.Port, d.DbName)
}
if d.SSLMode != "" {
// This will be overridden if a CA or client cert is provided
params.Set("tls", d.SSLMode)
}
if d.SSLCACert != "" {
caCert, err := os.ReadFile(d.SSLCACert)
if err != nil {
return "", fmt.Errorf("failed to read CA cert file %s: %w", d.SSLCACert, err)
}
if tlsConfig.RootCAs == nil {
tlsConfig.RootCAs = x509.NewCertPool()
}
if !tlsConfig.RootCAs.AppendCertsFromPEM(caCert) {
return "", fmt.Errorf("failed to append CA cert file %s: %w", d.SSLCACert, err)
}
params.Set("tls", "custom")
}
if d.SSLClientCert != "" && d.SSLClientKey != "" {
cert, err := tls.LoadX509KeyPair(d.SSLClientCert, d.SSLClientKey)
if err != nil {
return "", fmt.Errorf("failed to load client cert/key pair: %w", err)
}
tlsConfig.Certificates = []tls.Certificate{cert}
params.Set("tls", "custom")
}
if params.Get("tls") == "custom" {
// Register the custom TLS config
err := mysql.RegisterTLSConfig("custom", tlsConfig)
if err != nil {
return "", fmt.Errorf("failed to register custom TLS config: %w", err)View on GitHub (pinned to 909b515798)
Solutions
- Convert the certificate to PEM: `openssl x509 -inform der -in ca.der -out ca.pem`
- Verify content: file should start with '-----BEGIN CERTIFICATE-----' (`head -1 ca.pem`)
- Ensure you point at the CA certificate, not a client key or CSR
Example fix
// before openssl x509 -inform der -in ca.cer -out ca.pem # or check head -1 // after ssl_ca_cert: /etc/crowdsec/db/ca.pem # PEM, '-----BEGIN CERTIFICATE-----'
Defensive patterns
Strategy: validation
Validate before calling
pemBytes, _ := os.ReadFile(caPath); if block, _ := pem.Decode(pemBytes); block == nil || block.Type != "CERTIFICATE" { return fmt.Errorf("%s is not a PEM certificate", caPath) } Try / catch
if _, err := dbCfg.ConnectionString(); err != nil { if strings.Contains(err.Error(), "failed to append CA cert") { log.Fatalf("CA file is not valid PEM: %v", err) } } Prevention
- Always distribute CA certs in PEM format
- Validate with `openssl x509 -in ca.pem -noout` before deploying
- Confirm the first line is '-----BEGIN CERTIFICATE-----'
When it happens
Trigger: ssl_ca_cert points to an existing but non-PEM file: DER-encoded cert, an already-chained/binary file, empty file, or a private key instead of a certificate.
Common situations: Users export certs in DER format from Windows tooling; download HTML error page instead of cert; paste key material where a certificate is expected.
Related errors
- failed to load client cert/key pair: %w
- failed to read CA cert file %s: %w
- failed to register custom TLS config: %w
- certificate revoked by OCSP
- certificate revoked by CRL
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/9160d2adaa5fb92b.
Report an issue: GitHub.