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

  1. Inspect the file at the reported path and confirm it contains two integers like `max 100000` or `200000 100000`.
  2. Fix the container's cgroup mount so the v2 unified hierarchy is exposed at the expected path.
  3. Boot the host/container with cgroup v2 unified hierarchy (systemd.unified_cgroup_hierarchy=1) if v2 limits are intended.
  4. 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

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


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)