{"record":{"id":"d08f4e44dc416b1f","repo":"crowdsecurity/crowdsec","slug":"failed-to-read-ca-cert-w","errorCode":null,"errorMessage":"failed to read ca cert: %w","messagePattern":"failed to read ca cert: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/acquisition/modules/http/config.go","lineNumber":188,"sourceCode":"\nfunc (c *Configuration) NewTLSConfig() (*tls.Config, error) {\n\ttlsConfig := tls.Config{\n\t\tInsecureSkipVerify: c.TLS.InsecureSkipVerify,\n\t}\n\n\tif c.TLS.ServerCert != \"\" && c.TLS.ServerKey != \"\" {\n\t\tcert, err := tls.LoadX509KeyPair(c.TLS.ServerCert, c.TLS.ServerKey)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to load server cert/key: %w\", err)\n\t\t}\n\n\t\ttlsConfig.Certificates = []tls.Certificate{cert}\n\t}\n\n\tif c.AuthType == \"mtls\" && c.TLS.CaCert != \"\" {\n\t\tcaCert, err := os.ReadFile(c.TLS.CaCert)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to read ca cert: %w\", err)\n\t\t}\n\n\t\tcaCertPool, err := x509.SystemCertPool()\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to load system cert pool: %w\", err)\n\t\t}\n\n\t\tif caCertPool == nil {\n\t\t\tcaCertPool = x509.NewCertPool()\n\t\t}\n\n\t\tcaCertPool.AppendCertsFromPEM(caCert)\n\t\ttlsConfig.ClientCAs = caCertPool\n\t\ttlsConfig.ClientAuth = tls.RequireAndVerifyClientCert\n\t}\n\n\treturn &tlsConfig, nil\n}","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/acquisition/modules/http/config.go#L170-L206","documentation":"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.","triggerScenarios":"os.ReadFile(c.TLS.CaCert) errors when c.AuthType == \"mtls\" and c.TLS.CaCert is set, in NewTLSConfig (callers: RunServer, NewDialer).","commonSituations":"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.","solutions":["Verify the ca_cert path exists and is readable: `ls -l <path>` and `cat <path> | head`.","Fix the path in the acquisition YAML to the actual CA bundle location.","Check file permissions for the user crowdsec runs as (often needs group 'crowdsec' or 0644).","Confirm AuthType 'mtls' is intended — if you only need server TLS verification, ensure the ca path is correct for that trust anchor instead."],"exampleFix":"// before\nauth_type: mtls\nca_cert: /etc/ssl/certs/myca.pem  # doesn't exist\n// after\nauth_type: mtls\nca_cert: /etc/crowdsec/ssl/ca.crt","handlingStrategy":"validation","validationCode":"const fs = require('fs');\nif (!fs.existsSync(caPath)) throw new Error(`CA cert missing: ${caPath}`);\nif (!fs.readFileSync(caPath, 'utf8').includes('BEGIN CERTIFICATE')) throw new Error('not a PEM cert');","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Store CA bundles in a fixed, documented path (e.g. /etc/crowdsec/ssl/ca.crt).","Make CA files world-readable (0644) or group-readable by the crowdsec user.","Re-verify ca_cert paths after any PKI/cert-renewal migration.","Use absolute paths in acquis.yaml; never rely on cwd."],"tags":["tls","certificates","http","file-io"],"backgroundTag":"file-read-failed","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}