risingwavelabs/risingwave · warning · std::io::Error

not a number

Error message

not a number

What it means

In cgroup v1 CPU limit detection, `get_cpu_limit_v1` reads the quota file and parses it as `i64`. If the trimmed content is not an integer, it maps the parse failure to `io::Error(InvalidData, "not a number")`.

Solutions

  1. Verify the path points to a real cgroup v1 cpu quota file containing an integer.
  2. Check the host is running cgroup v1 (on cgroup v2 hosts the v1 path logic won't find valid data).
  3. Ensure the container mounts /sys/fs/cgroup properly (privileged or correct volume).
  4. Upgrade RisingWave to prefer cgroup v2 detection where applicable.

Example fix

// before
let content = std::fs::read_to_string("/sys/fs/cgroup/cpu/cpu.cfs_quota_us")?;
// after (guard against non-numeric content)
let content = std::fs::read_to_string("/sys/fs/cgroup/cpu/cpu.cfs_quota_us")?;
if content.trim().parse::<i64>().is_err() {
    log::warn!("unexpected cgroup quota content: {content:?}, falling back");
    return Ok(max_value);
}
Defensive patterns

Strategy: fallback

Validate before calling

fn cgroup_v1_quota_ok(path: &str) -> bool {
    std::fs::read_to_string(path).map(|c| c.trim().parse::<i64>().is_ok()).unwrap_or(false)
}

Try / catch

match get_cpu_limit_v1(path, max) {
    Err(e) if e.kind() == std::io::ErrorKind::InvalidData => fallback_to_system_cpu(),
    other => other?,
}

Prevention

When it happens

Trigger: Reading a cgroup v1 `cpu.cfs_quota_us` file whose content is not a plain integer (unexpected format, whitespace artifacts, placeholder text, or wrong path passed as quota_path).

Common situations: Unusual container runtimes mounting nonstandard files at the cgroup path; misconfigured override of the quota path in tests/custom environments; cgroup v2 systems where the v1 file does not exist as expected.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

Thrown at src/utils/resource_util/src/lib.rs:314

            Ok(available_parallelism) => available_parallelism.get() as f32,
            Err(e) => panic!(
                "Failed to get available parallelism, error: {}",
                e.as_report()
            ),
        }
    }

    /// Returns the CPU limit when cgroup v1 is utilised.
    pub fn get_cpu_limit_v1(
        quota_path: &str,
        period_path: &str,
        max_value: f32,
    ) -> Result<f32, std::io::Error> {
        let content = std::fs::read_to_string(quota_path)?;
        let cpu_quota = content
            .trim()
            .parse::<i64>()
            .map_err(|_| std::io::Error::new(std::io::ErrorKind::InvalidData, "not a number"))?;
        // According to the kernel documentation, if the value is negative, it means no limit.
        // https://docs.kernel.org/scheduler/sched-bwc.html#management
        if cpu_quota < 0 {
            return Ok(max_value);
        }

        let cpu_period = super::util::read_usize(period_path)?;

        Ok((cpu_quota as f32) / (cpu_period as f32))
    }

    /// Returns the CPU limit when cgroup v2 is utilised.
    pub fn get_cpu_limit_v2(limit_path: &str, max_value: f32) -> Result<f32, std::io::Error> {
        let cpu_limit_string = fs_err::read_to_string(limit_path)?;

        let cpu_data: Vec<&str> = cpu_limit_string.split_whitespace().collect();
        match cpu_data.get(0..2) {
            Some(cpu_data_values) => {

View on GitHub (pinned to 6469eb736d)