{"record":{"id":"3f26bfa7bac4901f","repo":"risingwavelabs/risingwave","slug":"failed-to-read-client-certificate","errorCode":null,"errorMessage":"Failed to read client certificate","messagePattern":"Failed to read client certificate","errorType":"exception","errorClass":"PsqlError","httpStatus":null,"severity":"error","filePath":"src/utils/pgwire/src/ldap_auth.rs","lineNumber":136,"sourceCode":"                    PsqlError::StartupError(\n                        anyhow!(err)\n                            .context(\"Failed to add native CA certificate\")\n                            .into(),\n                    )\n                })?;\n            }\n        }\n        let tls_client_config = tls_client_config.with_root_certificates(root_cert_store);\n\n        if let Some(cert) = &self.cert {\n            let Some(key) = &self.key else {\n                return Err(PsqlError::StartupError(\n                    \"Client certificate provided without private key\".into(),\n                ));\n            };\n            let client_cert_bytes = fs::read(cert).map_err(|e| {\n                PsqlError::StartupError(\n                    anyhow!(e)\n                        .context(\"Failed to read client certificate\")\n                        .into(),\n                )\n            })?;\n            let client_key_bytes = fs::read(key).map_err(|e| {\n                PsqlError::StartupError(anyhow!(e).context(\"Failed to read client key\").into())\n            })?;\n            let client_certs = CertificateDer::pem_slice_iter(&client_cert_bytes)\n                .collect::<Result<Vec<_>, _>>()\n                .map_err(|e| {\n                    PsqlError::StartupError(\n                        anyhow!(e)\n                            .context(\"Failed to parse client certificate\")\n                            .into(),\n                    )\n                })?;\n\n            let client_private_key =","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/utils/pgwire/src/ldap_auth.rs#L118-L154","documentation":"During LDAP auth TLS setup with mutual (client) certificates, the configured client certificate file could not be read from disk. The IO error is wrapped with anyhow context \"Failed to read client certificate\" inside a PsqlError::StartupError.","triggerScenarios":"`init_client_config` calls `fs::read(cert)` on the configured client certificate path (after verifying the private key is also provided) and the read fails — path missing, unreadable, or a directory.","commonSituations":"Client cert path typo in LDAP connection settings; secret/cert not mounted in the container; permissions preventing the risingwave process from reading the cert file.","solutions":["Verify the client certificate path exists and is a readable file.","Fix permissions (chown/chmod) so the risingwave process can read the file.","In containers/Kubernetes, mount the client certificate secret at the configured path.","If mutual TLS is not required, remove the client certificate configuration."],"exampleFix":"// before\nclient_cert = \"/secrets/ldap-client.crt\"  // not mounted\n// after: mount secret first\nclient_cert = \"/etc/risingwave/certs/ldap-client.crt\"","handlingStrategy":"validation","validationCode":"use std::path::Path;\nfn client_cert_readable(cert: &str, key: &str) -> Result<(), String> {\n    for p in [cert, key] {\n        let path = Path::new(p);\n        if !path.is_file() { return Err(format!(\"missing file: {}\", p)); }\n        std::fs::File::open(path).map_err(|e| format!(\"{}: {}\", p, e))?;\n    }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":"match err {\n    PsqlError::StartupError(e) if e.to_string().contains(\"Failed to read client certificate\") => {\n        eprintln!(\"check client cert path/permissions/mounts: {}\", e);\n    }\n    other => return Err(other),\n}","preventionTips":["Always provide both client cert and key together, mounted read-only.","Verify cert/key file presence in startup health checks.","Keep cert files owned by the user running the risingwave process."],"tags":["ldap","tls","certificate","file-io","mutual-tls"],"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-14T21:17:11.552Z"}