crowdsecurity/crowdsec · error

failed to read ca cert: %w

Error message

failed to read ca cert: %w

What it means

When AuthType is "mtls" and a CA certificate path (TLS.CaCert) is configured, NewTLSConfig reads the CA bundle with os.ReadFile to build the trust pool. A read failure (missing file, permissions) returns "failed to read ca cert: %w". This error means the CA file needed to authenticate peers couldn't be loaded.

Source

Thrown at pkg/acquisition/modules/http/config.go:188

func (c *Configuration) NewTLSConfig() (*tls.Config, error) {
	tlsConfig := tls.Config{
		InsecureSkipVerify: c.TLS.InsecureSkipVerify,
	}

	if c.TLS.ServerCert != "" && c.TLS.ServerKey != "" {
		cert, err := tls.LoadX509KeyPair(c.TLS.ServerCert, c.TLS.ServerKey)
		if err != nil {
			return nil, fmt.Errorf("failed to load server cert/key: %w", err)
		}

		tlsConfig.Certificates = []tls.Certificate{cert}
	}

	if c.AuthType == "mtls" && c.TLS.CaCert != "" {
		caCert, err := os.ReadFile(c.TLS.CaCert)
		if err != nil {
			return nil, fmt.Errorf("failed to read ca cert: %w", err)
		}

		caCertPool, err := x509.SystemCertPool()
		if err != nil {
			return nil, fmt.Errorf("failed to load system cert pool: %w", err)
		}

		if caCertPool == nil {
			caCertPool = x509.NewCertPool()
		}

		caCertPool.AppendCertsFromPEM(caCert)
		tlsConfig.ClientCAs = caCertPool
		tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert
	}

	return &tlsConfig, nil
}

View on GitHub (pinned to 909b515798)

Solutions

  1. Verify the ca_cert path exists and is readable: `ls -l <path>` and `cat <path> | head`.
  2. Fix the path in the acquisition YAML to the actual CA bundle location.
  3. Check file permissions for the user crowdsec runs as (often needs group 'crowdsec' or 0644).
  4. Confirm AuthType 'mtls' is intended — if you only need server TLS verification, ensure the ca path is correct for that trust anchor instead.

Example fix

// before
auth_type: mtls
ca_cert: /etc/ssl/certs/myca.pem  # doesn't exist
// after
auth_type: mtls
ca_cert: /etc/crowdsec/ssl/ca.crt
Defensive patterns

Strategy: validation

Validate before calling

const fs = require('fs');
if (!fs.existsSync(caPath)) throw new Error(`CA cert missing: ${caPath}`);
if (!fs.readFileSync(caPath, 'utf8').includes('BEGIN CERTIFICATE')) throw new Error('not a PEM cert');

Prevention

When it happens

Trigger: os.ReadFile(c.TLS.CaCert) errors when c.AuthType == "mtls" and c.TLS.CaCert is set, in NewTLSConfig (callers: RunServer, NewDialer).

Common situations: Typo in ca_cert path in the http acquisition config; CA file removed during cert renewal; config copied from another machine where the CA lives elsewhere; permission denied for the crowdsec service user.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


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