risingwavelabs/risingwave · error · PsqlError

Failed to set client certificate

Error message

Failed to set client certificate

What it means

After both client certificate and key parse successfully, rustls' ClientConfig::with_client_auth_cert(cert_chain, key_der) is called; it fails if the private key does not match the first certificate in the chain (or the key type is otherwise rejected). RisingWave wraps that as this StartupError: the mTLS identity is internally inconsistent.

Source

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

                .collect::<Result<Vec<_>, _>>()
                .map_err(|e| {
                    PsqlError::StartupError(
                        anyhow!(e)
                            .context("Failed to parse client certificate")
                            .into(),
                    )
                })?;

            let client_private_key =
                PrivateKeyDer::from_pem_slice(&client_key_bytes).map_err(|e| {
                    PsqlError::StartupError(anyhow!(e).context("Failed to parse client key").into())
                })?;

            tls_client_config
                .with_client_auth_cert(client_certs, client_private_key)
                .map_err(|err| {
                    PsqlError::StartupError(
                        anyhow!(err)
                            .context("Failed to set client certificate")
                            .into(),
                    )
                })
        } else {
            Ok(tls_client_config.with_no_client_auth())
        }
    }
}

/// LDAP configuration extracted from HBA entry
#[derive(Debug, Clone)]
pub struct LdapConfig {
    /// LDAP server address
    pub server: String,
    /// LDAP bind DN template or search base
    pub base_dn: Option<String>,
    /// LDAP search filter template

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Verify cert and key match: compare modulus/public key hash (openssl x509 -noout -modem vs openssl rsa -noout -modulus)
  2. Regenerate cert+key as a pair and update both config paths
  3. Ensure the leaf client certificate is the first entry in the cert file, followed by intermediates
  4. If mTLS is not required by the LDAP server, remove the client cert/key config to fall into the with_no_client_auth branch

Example fix

// before: mismatched pair
client_cert = '/etc/rw/certs/old.crt'   // key regenerated since
// after
openssl req -x509 -newkey rsa:2048 -nodes -keyout client.key -out client.crt ...
client_cert = '/etc/rw/certs/client.crt'
client_key  = '/etc/rw/certs/client.key'
Defensive patterns

Strategy: validation

Validate before calling

// deploy-time check that cert and key match
# openssl x509 -noout -pubkey -in client.crt | sha256sum
# openssl pkey -pubout -in client.key | sha256sum
# hashes must be equal before configuring mTLS

Try / catch

catch PsqlError::StartupError for 'Failed to set client certificate' and surface an explicit 'cert/key mismatch — regenerate as a pair' message

Prevention

When it happens

Trigger: tls_client_config.with_client_auth_cert(client_certs, client_private_key) returns Err — key/cert mismatch or invalid cert chain

Common situations: Mixing cert and key from different generations (regenerated the key but reused the old cert); cert chain ordering where leaf is not first; using a CA cert as the client cert with an unrelated key.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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