risingwavelabs/risingwave · error · PsqlError

Failed to parse CA certificate

Error message

Failed to parse CA certificate

What it means

The CA certificate file was read but its bytes could not be parsed as PEM certificate(s) by rustls-pemfile's `CertificateDer::pem_slice_iter`. The parse error is wrapped with anyhow context "Failed to parse CA certificate" inside a StartupError.

Source

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

            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")
            {
                root_cert_store.add(cert).map_err(|err| {
                    PsqlError::StartupError(
                        anyhow!(err)
                            .context("Failed to add native CA certificate")
                            .into(),

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Convert the certificate to PEM format (`openssl x509 -inform der -in cert.der -out cert.pem`).
  2. Verify the file contains `-----BEGIN CERTIFICATE-----` blocks.
  3. Re-download/re-export the CA certificate to fix corruption.
  4. Validate with `openssl x509 -in cert.pem -text -noout` before configuring it.

Example fix

// before: DER cert configured
openssl x509 -outform der -in ca.crt -out ca.pem  # wrong
// after: PEM cert
openssl x509 -outform pem -in ca.crt -out ca.pem
Defensive patterns

Strategy: validation

Validate before calling

fn is_pem_cert(path: &str) -> Result<(), String> {
    let s = std::fs::read_to_string(path).map_err(|e| e.to_string())?;
    if s.contains("-----BEGIN CERTIFICATE-----") { Ok(()) }
    else { Err("file is not PEM encoded".into()) }
}

Try / catch

match err {
    PsqlError::StartupError(e) if e.to_string().contains("Failed to parse CA certificate") => {
        eprintln!("convert cert to PEM: {}", e);
    }
    other => return Err(other),
}

Prevention

When it happens

Trigger: `init_client_config` iterates `CertificateDer::pem_slice_iter(&ca_cert_bytes)` on the file read from the configured ca_cert path and the iterator yields Err — the file is not valid PEM (DER-encoded file, concatenated junk, HTML error page, empty file).

Common situations: Providing a DER (.der/.crt binary) certificate where PEM is required; downloading a cert and saving the HTML response; corrupted or truncated certificate file.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/df417fbff73a48da. Report an issue: GitHub.