{"record":{"id":"681d1654bdb2b2d2","repo":"crowdsecurity/crowdsec","slug":"while-opening-cert-file-w","errorCode":null,"errorMessage":"while opening cert file: %w","messagePattern":"while opening cert file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/csconfig/tls.go","lineNumber":75,"sourceCode":"\t}\n\n\tcaCertPool, err := x509.SystemCertPool()\n\tif err != nil {\n\t\tlog.Warnf(\"Error loading system CA certificates: %s\", err)\n\t}\n\n\tif caCertPool == nil {\n\t\tcaCertPool = x509.NewCertPool()\n\t}\n\n\t// the > condition below is a weird way to say \"if a client certificate is required\"\n\t// see https://pkg.go.dev/crypto/tls#ClientAuthType\n\tif clientAuthType > tls.RequestClientCert && t.CACertPath != \"\" {\n\t\tlog.Infof(\"(tls) Client Auth Type set to %s\", clientAuthType.String())\n\n\t\tcaCert, err := os.ReadFile(t.CACertPath)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"while opening cert file: %w\", err)\n\t\t}\n\n\t\tcaCertPool.AppendCertsFromPEM(caCert)\n\t}\n\n\treturn &tls.Config{\n\t\tServerName: t.ServerName, //should it be removed ?\n\t\tClientAuth: clientAuthType,\n\t\tClientCAs:  caCertPool,\n\t\tMinVersion: tls.VersionTLS12, // TLS versions below 1.2 are considered insecure - see https://www.rfc-editor.org/rfc/rfc7525.txt for details\n\t}, nil\n}\n","sourceCodeStart":57,"sourceCodeEnd":88,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/csconfig/tls.go#L57-L88","documentation":"GetTLSConfig, when a client-auth mode stricter than RequestClientCert is set and CACertPath is non-empty, reads the CA certificate bundle with os.ReadFile to build the trust pool. Any read failure (missing file, permission denied, is-a-directory) is wrapped as 'while opening cert file'. Without the CA the server cannot verify client certificates, so startup fails fast.","triggerScenarios":"client_verification is set to RequireAndVerifyClientCert / VerifyClientCertIfGiven (anything > RequestClientCert) and tls.ca_cert_path points to a nonexistent, unreadable, or wrong file.","commonSituations":"CA path typo in config.yaml, CA file not mounted/copied into a container, wrong ownership so the crowdsec user cannot read it, or pointing at a directory or key file instead of the CA PEM bundle.","solutions":["Verify the file exists at the configured path: `ls -l <ca_cert_path>` and fix the path in the tls config if it doesn't.","Fix permissions/ownership so the crowdsec process user can read it: `chown crowdsec:crowdsec ca.pem && chmod 644 ca.pem`.","Ensure the path points to a PEM CA bundle (not a directory, not the private key): check `head -1` shows '-----BEGIN CERTIFICATE-----'.","In containers, confirm the CA file is mounted into the container at the exact configured path.","If client cert verification is not intended, set client_verification: NoClientCert and remove ca_cert_path."],"exampleFix":"// before (config.yaml)\ntls:\n  ca_cert_path: /etc/crowdsec/ssl/ca.crt   # file does not exist\n// after\ntls:\n  ca_cert_path: /etc/crowdsec/ssl/ca.pem   # existing PEM bundle\n# or:\n$ sudo chown crowdsec:crowdsec /etc/crowdsec/ssl/ca.pem && sudo chmod 644 /etc/crowdsec/ssl/ca.pem","handlingStrategy":"validation","validationCode":"info, err := os.Stat(tlsCfg.CACertPath)\nif err != nil {\n    return fmt.Errorf(\"ca_cert_path %q: %w\", tlsCfg.CACertPath, err)\n}\nif info.IsDir() {\n    return fmt.Errorf(\"ca_cert_path %q is a directory\", tlsCfg.CACertPath)\n}\nif f, err := os.Open(tlsCfg.CACertPath); err == nil {\n    defer f.Close() // readable by current user\n}","typeGuard":null,"tryCatchPattern":"if _, err := tlsCfg.GetTLSConfig(); err != nil {\n    var perr *fs.PathError\n    if errors.As(err, &perr) {\n        log.Fatalf(\"CA cert unreadable: %s -> %v\", perr.Path, perr.Err)\n    }\n    return err\n}","preventionTips":["Pre-provision CA files and verify with `openssl x509 -in ca.pem -noout` before config rollout.","Set stable ownership (crowdsec user) and mode 644 on cert files.","In containers, mount CA bundles read-only at the exact configured path."],"tags":["tls","certificates","file","config"],"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-14T00:17:10.932Z"}