risingwavelabs/risingwave · error · SchemaRegistryClientError::ParsePem

parse ca file error: {0}

Error message

parse ca file error: {0}

What it means

SchemaRegistryClientError::ParsePem is returned when the CA certificate file was read but its contents could not be parsed as PEM certificates (reqwest::Error from the certificate builder). It indicates malformed or non-certificate content in the configured CA file.

Source

Thrown at src/connector/src/schema/schema_registry/client.rs:132

    retry_config: SchemaRegistryRetryConfig,
}

#[derive(Debug, thiserror::Error)]
#[error("all request confluent registry all timeout, {context}\n{}", errs.iter().map(|e| format!("\t{}", e.as_report())).join("\n"))]
pub struct ConcurrentRequestError {
    errs: Vec<itertools::Either<RequestError, tokio::task::JoinError>>,
    context: String,
}

type SrResult<T> = Result<T, ConcurrentRequestError>;

#[derive(thiserror::Error, Debug)]
pub enum SchemaRegistryClientError {
    #[error(transparent)]
    InvalidOption(#[from] InvalidOptionError),
    #[error("read ca file error: {0}")]
    ReadFile(#[source] std::io::Error),
    #[error("parse ca file error: {0}")]
    ParsePem(#[source] reqwest::Error),
    #[error("build schema registry client error: {0}")]
    Build(#[source] reqwest::Error),
}

impl TryFrom<&ConfluentSchemaRegistryConnection> for Client {
    type Error = InvalidOptionError;

    fn try_from(value: &ConfluentSchemaRegistryConnection) -> Result<Self, Self::Error> {
        let urls = handle_sr_list(value.url.as_str())?;

        Client::new(
            urls,
            &SchemaRegistryConfig {
                username: value.username.clone(),
                password: value.password.clone(),
                ..Default::default()
            },

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Validate the file: openssl x509 -in ca.pem -noout -text (must parse as a certificate).
  2. Ensure the file starts with -----BEGIN CERTIFICATE----- and re-export the cert in PEM format.
  3. Verify you did not accidentally provide the private key or a binary keystore.
  4. Regenerate/redownload the CA cert from the source (e.g. kubectl get secret ... ca.crt).

Example fix

// before
ca_cert: "/certs/keystore.p12"
// after
ca_cert: "/certs/ca.pem"  # openssl x509 -in /certs/ca.pem -noout
Defensive patterns

Strategy: validation

Validate before calling

let pem = std::fs::read_to_string(&ca_path)?;
if !pem.contains("-----BEGIN CERTIFICATE-----") {
    return Err(format!("{} is not a PEM certificate", ca_path));
}
// optional deep validation
// openssl x509 -in ca.pem -noout

Try / catch

match build_client(conn) {
    Ok(c) => c,
    Err(SchemaRegistryClientError::ParsePem(e)) => {
        eprintln!("invalid PEM in CA file: {}", e); return Err(e.into());
    }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Building the schema registry Client when add_ca_certificate / pem parsing of the file contents fails — e.g. the file is empty, contains a private key instead of a cert, or has invalid base64/PEM headers.

Common situations: Downloading the wrong cert (private key or chain), truncated copy-paste of the PEM, concatenating certs incorrectly, or pointing the CA option at a JKS/PKCS12 keystore.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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