risingwavelabs/risingwave · error · PsqlError

Failed to read CA certificate

Error message

Failed to read CA certificate

What it means

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.

Source

Thrown at src/utils/pgwire/src/ldap_auth.rs:98

            _ => ReqCertPolicy::Demand, // Default to demand
        };

        Self {
            ca_cert,
            cert,
            key,
            req_cert,
        }
    }

    /// Initialize rustls ClientConfig based on TLS configuration
    fn init_client_config(&self) -> PsqlResult<rustls::ClientConfig> {
        let tls_client_config = rustls::ClientConfig::builder();

        let mut root_cert_store = rustls::RootCertStore::empty();
        if let Some(tls_config) = &self.ca_cert {
            let ca_cert_bytes = fs::read(tls_config).map_err(|e| {
                PsqlError::StartupError(anyhow!(e).context("Failed to read CA certificate").into())
            })?;
            for cert in CertificateDer::pem_slice_iter(&ca_cert_bytes) {
                let cert = cert.map_err(|e| {
                    PsqlError::StartupError(
                        anyhow!(e).context("Failed to parse CA certificate").into(),
                    )
                })?;
                root_cert_store.add(cert).map_err(|err| {
                    PsqlError::StartupError(
                        anyhow!(err).context("Failed to add CA certificate").into(),
                    )
                })?;
            }
        } else {
            // If ca certs is not present, load system native certs.
            for cert in
                rustls_native_certs::load_native_certs().expect("could not load platform certs")
            {

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Verify the `ca_cert` path in the LDAP configuration points to an existing PEM file.
  2. Fix file permissions so the risingwave process can read the certificate.
  3. In containerized deployments, ensure the certificate is mounted into the container at that path.
  4. If no custom CA is needed, remove the ca_cert setting so system native certs are used instead.

Example fix

// before
tls_ca_cert = "/etc/ssl/certs/corporate-ca.pem"  // file absent
// after
tls_ca_cert = "/etc/risingwave/certs/corporate-ca.pem"  // mounted and readable
Defensive patterns

Strategy: validation

Validate before calling

use std::path::Path;
fn ca_cert_readable(path: &str) -> Result<(), String> {
    let p = Path::new(path);
    if !p.is_file() { return Err(format!("not a file: {}", path)); }
    std::fs::File::open(p).map(|_| ()).map_err(|e| e.to_string())
}

Try / catch

match err {
    PsqlError::StartupError(e) if e.to_string().contains("Failed to read CA certificate") => {
        eprintln!("check ca_cert path/permissions: {}", e);
    }
    other => return Err(other),
}

Prevention

When it happens

Trigger: `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.

Common situations: Typo in the CA cert path in LDAP connection config; file not mounted/present in the container; wrong permissions for the risingwave process 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 risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/772c2833ccbc4c35. Report an issue: GitHub.