risingwavelabs/risingwave · error · SchemaRegistryClientError::ReadFile

read ca file error: {0}

Error message

read ca file error: {0}

What it means

SchemaRegistryClientError::ReadFile is returned when the CA certificate file configured for the schema registry TLS connection cannot be read from disk. It wraps the underlying std::io::Error (e.g. NotFound, PermissionDenied). The client builds an reqwest TLS config from this PEM file, so it fails before any network request is made.

Source

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

    password: Option<String>,

    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(),

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Verify the CA file path exists and is readable: ls -l <path> and cat <path> | head.
  2. Mount the CA certificate into the container/pod or fix the path in the connection options.
  3. Fix file permissions so the RisingWave process user can read it.
  4. If no custom CA is actually needed, remove the CA option so the system trust store is used.

Example fix

// before (client.rs)
let ca = std::fs::read(&ca_path)?;
// after (defensive check in caller)
assert!(std::path::Path::new("/certs/ca.pem").exists(), "CA file missing");
let ca = std::fs::read("/certs/ca.pem")?;
Defensive patterns

Strategy: validation

Validate before calling

let path = std::path::Path::new(&ca_path);
if !path.is_file() {
    return Err(format!("CA file not found or not a file: {}", ca_path));
}
std::fs::File::open(path)?.metadata()?; // open-check before client build

Try / catch

match build_client(conn) {
    Ok(c) => c,
    Err(SchemaRegistryClientError::ReadFile(io)) => {
        eprintln!("CA file unreadable: {}", io); return Err(io.into());
    }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Constructing a schema registry Client via TryFrom<&ConfluentSchemaRegistryConnection> when the connection specifies a CA certificate path whose file cannot be opened/read (std::fs::read fails).

Common situations: Typo in the CA cert path, file not mounted into the container, missing read permissions, or the file was deleted/moved after config was written.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


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