risingwavelabs/risingwave · error · SecretError

I/O error: {0}

Error message

I/O error: {0}

What it means

SecretError::IoError wraps std::io::Error (via #[from]) and is raised when an I/O operation performed while reading or writing secrets fails — e.g. reading secret material from a local file or interacting with a file-backed secret store.

Source

Thrown at src/common/secret/src/error.rs:31

// limitations under the License.

pub use anyhow::anyhow;
use thiserror::Error;
use thiserror_ext::Construct;

use super::SecretId;

pub type SecretResult<T> = Result<T, SecretError>;

#[derive(Error, Debug, Construct)]
pub enum SecretError {
    #[error("secret not found: {0}")]
    ItemNotFound(SecretId),

    #[error("decode utf8 error: {0}")]
    DecodeUtf8Error(#[from] std::string::FromUtf8Error),

    #[error("I/O error: {0}")]
    IoError(#[from] std::io::Error),

    #[error("unspecified secret ref type: {0}")]
    UnspecifiedRefType(SecretId),

    #[error("failed to encrypt or decrypt the secret")]
    AesError,

    #[error("ser/de proto message error: {0}")]
    ProtoError(#[from] bincode::Error),

    #[error(transparent)]
    Internal(#[from] anyhow::Error),
}

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Check the underlying io::Error (it is Displayed via 'I/O error: ...') and fix the path/permissions it reports.
  2. Verify the secret file exists and is readable by the RisingWave process user.
  3. Mount/copy the secret file into the container or host correctly.
  4. If transient (network FS), retry the operation after restoring access.

Example fix

// before
let secret = std::fs::read_to_string("/secrets/kafka_pass")?; // No such file

// after
// ensure the file is mounted, then verify before use
let path = std::path::Path::new("/secrets/kafka_pass");
assert!(path.exists(), "secret file missing");
let secret = std::fs::read_to_string(path)?;
Defensive patterns

Strategy: try-catch

Validate before calling

// Check file-backed secret availability before use:
fn secret_file_readable(path: &str) -> bool {
    std::fs::File::open(path).is_ok()
}

Try / catch

match manager.get(id).await {
    Ok(s) => s,
    Err(SecretError::IoError(e)) if e.kind() == std::io::ErrorKind::NotFound => {
        return Err(anyhow!("secret file missing: {e}; check volume mount"));
    }
    Err(SecretError::IoError(e)) if e.kind() == std::io::ErrorKind::PermissionDenied => {
        return Err(anyhow!("secret file unreadable: {e}; fix file permissions"));
    }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Reading a secret from a local file path that does not exist, lacks permissions, or hits a device error during secret creation/fetch; any std::io operation in the secret code path that returns Err is auto-converted into this variant.

Common situations: Configured secret file path is wrong or the file was deleted; running the process as a user without read permission on the secret file; disk/network (NFS) failures while accessing the secret store; container mounts missing the secret volume.

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/f67e37b969ae8c99. Report an issue: GitHub.