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
- Verify the path points to a real cgroup v1 cpu quota file containing an integer.
- Check the host is running cgroup v1 (on cgroup v2 hosts the v1 path logic won't find valid data).
- Ensure the container mounts /sys/fs/cgroup properly (privileged or correct volume).
- 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
- Verify cgroup v1 paths exist before reading them.
- Run containers with proper cgroup mounts.
- Detect cgroup version (v1 vs v2) before choosing the reader.
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
- Failed to get available parallelism, error
- failed to parse, path
- Invalid format in Cgroup CPU interface file, path
- <parse error of commit_checkpoint_interval
- {0}
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)