crowdsecurity/crowdsec · error

failed to read CA cert file %s: %w

Error message

failed to read CA cert file %s: %w

What it means

For MySQL connections, ConnectionString reads the configured SSL CA certificate (db_config.ssl_ca_cert) with os.ReadFile to build the TLS RootCAs pool. Any read failure is wrapped as 'failed to read CA cert file %s: %w'. This runs whenever a MySQL connection string is built (e.g. NewClient at startup or `cscli` commands).

Source

Thrown at pkg/csconfig/database.go:170

		if systemRootCAs != nil {
			tlsConfig.RootCAs = systemRootCAs
		}

		if d.isSocketConfig() {
			connString = fmt.Sprintf("%s:%s@unix(%s)/%s", d.User, d.Password, d.DbPath, d.DbName)
		} 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")
		}

View on GitHub (pinned to 909b515798)

Solutions

  1. Verify the ssl_ca_cert path exists and is readable by the crowdsec/cscli user (`ls -l`, `cat` the file)
  2. Use an absolute path in db_config.ssl_ca_cert
  3. If the CA file was rotated, restore/redeploy it or update the path

Example fix

// before
ssl_ca_cert: ./ca.pem
// after
ssl_ca_cert: /etc/crowdsec/db/ca.pem
Defensive patterns

Strategy: validation

Validate before calling

if _, err := os.ReadFile(sslCACert); err != nil { return fmt.Errorf("ssl_ca_cert %q unreadable: %w", sslCACert, err) }

Try / catch

connStr, err := dbCfg.ConnectionString(); if err != nil { log.Fatalf("db connection string failed (check ssl_ca_cert path): %v", err) }

Prevention

When it happens

Trigger: Database config sets ssl_ca_cert to a path that does not exist, is unreadable (permissions), or is a directory.

Common situations: Typo in ssl_ca_cert path; cert file deleted during rotation; running cscli as a user who cannot read the root-owned CA file; relative path resolved from wrong working directory.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06). Data as JSON: /api/errors/d8c445aeeff774e4. Report an issue: GitHub.