influxdata/influxdb · critical
CA certificate PEM should be valid
Error message
CA certificate PEM should be valid
What it means
ConnectionBuilder in core/client_util attaches a custom root CA for TLS by parsing the configured PEM with reqwest::Certificate::from_pem and .expect()ing success, so a malformed PEM panics the process instead of returning an error. from_pem requires PEM-encoded X.509 CERTIFICATE blocks; it rejects DER bytes, truncated files, wrong block types (e.g. a PRIVATE KEY block), or PEM surrounded by unrelated text.
Source
Thrown at core/client_util/src/connection.rs:187
.connect_timeout(self.connect_timeout)
.timeout(self.timeout);
Ok(endpoint)
}
fn compose_middleware(self, channel: Channel, endpoint: Endpoint) -> Connection {
let headers_map: HeaderMap = self.headers.iter().cloned().collect();
// Compose channel with new tower middleware stack
let grpc_connection = tower::ServiceBuilder::new()
.layer(SetRequestHeadersLayer::new(self.headers))
.service(channel);
let mut http_builder = reqwest::Client::builder()
.connection_verbose(true)
.default_headers(headers_map);
if let Some(pem) = &self.ca_certificate_pem {
let cert =
reqwest::Certificate::from_pem(pem).expect("CA certificate PEM should be valid");
http_builder = http_builder.add_root_certificate(cert);
}
let http_client = http_builder
.build()
.expect("reqwest::Client should have built");
let http_connection = HttpConnection::new(endpoint.uri().clone(), http_client);
Connection::new(grpc_connection, http_connection)
}
/// Set the `User-Agent` header sent by this client.
pub fn user_agent(self, user_agent: impl Into<String>) -> Self {
Self {
user_agent: user_agent.into(),
..self
}
}View on GitHub (pinned to d28e26e048)
Solutions
- Validate the file first: openssl x509 -in ca.pem -noout -text must succeed
- If the cert is DER, convert it: openssl x509 -inform der -in ca.der -out ca.pem
- Confirm the file contains only -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- sections and nothing else
- Parse defensively in your own code: call reqwest::Certificate::from_pem(...)? yourself before building the connection and propagate the error
Example fix
// before: relies on the library's expect and panics
let conn = ConnectionBuilder::new(uri).ca_certificate_pem(pem_bytes).connect();
// after: validate first, surface a real error
let cert = reqwest::Certificate::from_pem(&pem_bytes)
.context("CA certificate file is not valid PEM")?;
let conn = ConnectionBuilder::new(uri).ca_certificate_pem(pem_bytes).connect();
Defensive patterns
Strategy: validation
Validate before calling
// validate the PEM before handing it to the connection builder
fn valid_pem(pem: &[u8]) -> bool {
reqwest::Certificate::from_pem(pem).is_ok()
}
if let Some(pem) = &config.ca_certificate_pem {
anyhow::ensure!(valid_pem(pem), "ca_certificate_pem is not a valid PEM certificate");
}
Try / catch
match reqwest::Certificate::from_pem(&pem_bytes) {
Ok(cert) => builder = builder.add_root_certificate(cert),
Err(e) => return Err(anyhow!("invalid CA PEM: {e}; run: openssl x509 -in ca.pem -noout -text")),
}
Prevention
- Run openssl x509 -in ca.pem -noout -text as part of deployment checks
- Never point ca_certificate_pem at a key file or DER blob; convert DER with openssl x509 -inform der
- Fetch certs by pinned path from your secret store instead of ad-hoc curl/downloads
- Watch process logs at startup - this path panics rather than returning an error
When it happens
Trigger: Setting ca_certificate_pem from a file that is not a valid PEM certificate: a DER-encoded cert, the TLS private key, an empty file, or certificate text mangled by copy/paste (missing BEGIN/END lines, embedded quotes or whitespace).
Common situations: Self-signed or private-CA deployments where the wrong secret is mounted; scripts that download a cert and capture an error page; passing the server key instead of the CA cert.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- cannot fit duration into u64
- metric should be in progress
- no metric in progress
- schema contains non-existent or column
- schema contains repeated column name
AI-assisted analysis of influxdata/influxdb@d28e26e048 (2026-08-16).
Data as JSON: /api/errors/c5c50f714b5200dc.
Report an issue: GitHub.