risingwavelabs/risingwave · warning · std::io::Error
Invalid format in Cgroup CPU interface file, path
Error message
Invalid format in Cgroup CPU interface file, path: {limit_path}, content: {cpu_limit_string} What it means
For cgroup v2, `get_cpu_limit_v2` expects the `cpu.max` file to contain exactly two whitespace-separated values (`quota period`). If the split yields no such pair, it returns `InvalidData` with this message describing the path and offending content.
Solutions
- Inspect the file at the reported path and confirm it contains two integers like `max 100000` or `200000 100000`.
- Fix the container's cgroup mount so the v2 unified hierarchy is exposed at the expected path.
- Boot the host/container with cgroup v2 unified hierarchy (systemd.unified_cgroup_hierarchy=1) if v2 limits are intended.
- Ignore/patch the limit detection to fall back to system CPU when the file format is unexpected.
Example fix
// before // cpu.max content: "" -> error // after: ensure file exists with valid content $ cat /sys/fs/cgroup/cpu.max max 100000
Defensive patterns
Strategy: fallback
Validate before calling
fn cpu_max_well_formed(path: &str) -> bool {
std::fs::read_to_string(path)
.map(|c| c.split_whitespace().count() == 2).unwrap_or(false)
} Try / catch
match get_cpu_limit_v2(path) {
Err(e) if e.kind() == std::io::ErrorKind::InvalidData => fallback_to_system_cpu(),
other => other?,
} Prevention
- Confirm the host uses cgroup v2 unified hierarchy.
- Log file content on failure (the error already embeds it) and alert on layout drift.
- Skip container-limit detection when cpu.max is absent or malformed.
When it happens
Trigger: Reading a cgroup v2 `cpu.max` file whose content doesn't match `"<quota> <period>"` (e.g. empty file, extra fields, or a non-cpu.max file passed as limit_path).
Common situations: Minimal/distros container images with odd cgroup layouts; nested cgroups where the resolved path holds unexpected content; runtimes that mount cgroup v1 paths while code probes v2.
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
- not a number
- Failed to get available parallelism, error
- failed to parse, path
- <parse error of commit_checkpoint_interval
- {0}
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/6e897010e50a3b35.
Report an issue: GitHub.
Appendix: source
Thrown at src/utils/resource_util/src/lib.rs:344
/// 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) => {
if cpu_data_values[0] == super::DEFAULT_CGROUP_MAX_INDICATOR {
return Ok(max_value);
}
let cpu_quota = cpu_data_values[0]
.parse::<usize>()
.map_err(|e| parse_error(limit_path, &cpu_limit_string, e))?;
let cpu_period = cpu_data_values[1]
.parse::<usize>()
.map_err(|e| parse_error(limit_path, &cpu_limit_string, e))?;
Ok((cpu_quota as f32) / (cpu_period as f32))
}
None => Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!(
"Invalid format in Cgroup CPU interface file, path: {limit_path}, content: {cpu_limit_string}"
),
)),
}
}
}
mod util {
/// Parses the filepath and checks for the existence of `controller_name` in the file.
pub fn parse_controller_enable_file_for_cgroup_v2(
file_path: &str,
controller_name: &str,
) -> bool {
match fs_err::read_to_string(file_path) {
Ok(controller_string) => {
for controller in controller_string.split_whitespace() {View on GitHub (pinned to 6469eb736d)