{"record":{"id":"772c2833ccbc4c35","repo":"risingwavelabs/risingwave","slug":"failed-to-read-ca-certificate","errorCode":null,"errorMessage":"Failed to read CA certificate","messagePattern":"Failed to read CA certificate","errorType":"exception","errorClass":"PsqlError","httpStatus":null,"severity":"error","filePath":"src/utils/pgwire/src/ldap_auth.rs","lineNumber":98,"sourceCode":"            _ => ReqCertPolicy::Demand, // Default to demand\n        };\n\n        Self {\n            ca_cert,\n            cert,\n            key,\n            req_cert,\n        }\n    }\n\n    /// Initialize rustls ClientConfig based on TLS configuration\n    fn init_client_config(&self) -> PsqlResult<rustls::ClientConfig> {\n        let tls_client_config = rustls::ClientConfig::builder();\n\n        let mut root_cert_store = rustls::RootCertStore::empty();\n        if let Some(tls_config) = &self.ca_cert {\n            let ca_cert_bytes = fs::read(tls_config).map_err(|e| {\n                PsqlError::StartupError(anyhow!(e).context(\"Failed to read CA certificate\").into())\n            })?;\n            for cert in CertificateDer::pem_slice_iter(&ca_cert_bytes) {\n                let cert = cert.map_err(|e| {\n                    PsqlError::StartupError(\n                        anyhow!(e).context(\"Failed to parse CA certificate\").into(),\n                    )\n                })?;\n                root_cert_store.add(cert).map_err(|err| {\n                    PsqlError::StartupError(\n                        anyhow!(err).context(\"Failed to add CA certificate\").into(),\n                    )\n                })?;\n            }\n        } else {\n            // If ca certs is not present, load system native certs.\n            for cert in\n                rustls_native_certs::load_native_certs().expect(\"could not load platform certs\")\n            {","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/utils/pgwire/src/ldap_auth.rs#L80-L116","documentation":"During LDAP authentication's TLS setup, the server tries to read the configured CA certificate file from disk and fails. The IO error (io::Error) is wrapped with anyhow context \"Failed to read CA certificate\" inside a PsqlError::StartupError.","triggerScenarios":"`init_client_config` calls `fs::read(tls_config)` on the configured `ca_cert` path and the file is missing, unreadable, or a directory — called from `establish_connection` when LDAP+TLS is configured.","commonSituations":"Typo in the CA cert path in LDAP connection config; file not mounted/present in the container; wrong permissions for the risingwave process user.","solutions":["Verify the `ca_cert` path in the LDAP configuration points to an existing PEM file.","Fix file permissions so the risingwave process can read the certificate.","In containerized deployments, ensure the certificate is mounted into the container at that path.","If no custom CA is needed, remove the ca_cert setting so system native certs are used instead."],"exampleFix":"// before\ntls_ca_cert = \"/etc/ssl/certs/corporate-ca.pem\"  // file absent\n// after\ntls_ca_cert = \"/etc/risingwave/certs/corporate-ca.pem\"  // mounted and readable","handlingStrategy":"validation","validationCode":"use std::path::Path;\nfn ca_cert_readable(path: &str) -> Result<(), String> {\n    let p = Path::new(path);\n    if !p.is_file() { return Err(format!(\"not a file: {}\", path)); }\n    std::fs::File::open(p).map(|_| ()).map_err(|e| e.to_string())\n}","typeGuard":null,"tryCatchPattern":"match err {\n    PsqlError::StartupError(e) if e.to_string().contains(\"Failed to read CA certificate\") => {\n        eprintln!(\"check ca_cert path/permissions: {}\", e);\n    }\n    other => return Err(other),\n}","preventionTips":["Validate cert file paths at config-load/startup time.","Mount certificates as read-only volumes with correct ownership.","Document required cert paths in deployment manifests."],"tags":["ldap","tls","certificate","file-io"],"backgroundTag":"file-read-failed","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}