neondatabase/neon · error

could not find memory subsystem

Error message

could not find memory subsystem

What it means

After loading the cgroup, CgroupWatcher::memory looks up the memory controller (MemController) among the cgroup's subsystems; if none is attached, this error is returned. On cgroup v2 the memory controller must be present in the cgroup's controllers and enabled by the parent's cgroup.subtree_control.

Source

Thrown at libs/vm_monitor/src/cgroup.rs:161

            updates
                .send((now, summary))
                .context("failed to send MemoryHistory")?;
        }

        unreachable!()
    }

    /// Get a handle on the memory subsystem.
    fn memory(&self) -> anyhow::Result<&MemController> {
        self.cgroup
            .subsystems()
            .iter()
            .find_map(|sub| match sub {
                Subsystem::Mem(c) => Some(c),
                _ => None,
            })
            .ok_or_else(|| anyhow!("could not find memory subsystem"))
    }

    /// Given a handle on the memory subsystem, returns the current memory information
    fn memory_usage(mem_controller: &MemController) -> MemoryStatus {
        let stat = mem_controller.memory_stat().stat;
        MemoryStatus {
            non_reclaimable: stat.active_anon + stat.inactive_anon,
        }
    }
}

// Helper function for `CgroupWatcher::watch`
fn ring_buf_recent_values_iter<T>(
    buf: &[T],
    last_value_idx: usize,
    count: usize,
) -> impl '_ + Iterator<Item = &T> {
    // Assertion carried over from `CgroupWatcher::watch`, to make the logic in this function

View on GitHub (pinned to 8f60b04da4)

Solutions

  1. Remove cgroup_disable=memory from the kernel cmdline and reboot
  2. Enable the controller for the subtree: echo +memory > /sys/fs/cgroup/<parent>/cgroup.subtree_control
  3. For containers, delegate the memory controller in the runtime/systemd unit (Delegate=memory)

Example fix

# before
GRUB_CMDLINE_LINUX="... cgroup_disable=memory"
# after
GRUB_CMDLINE_LINUX="..."
# plus enable it for the subtree
echo +memory > /sys/fs/cgroup/neon.slice/cgroup.subtree_control
Defensive patterns

Strategy: validation

Validate before calling

fn memory_controller_available() -> bool {
    std::fs::read_to_string("/sys/fs/cgroup/cgroup.controllers")
        .map(|c| c.split_whitespace().any(|s| s == "memory"))
        .unwrap_or(false)
}

anyhow::ensure!(memory_controller_available(), "memory cgroup controller missing; enable it in the parent's cgroup.subtree_control");

Try / catch

if let Err(e) = CgroupWatcher::new(name.clone()) {
    if e.to_string().contains("could not find memory subsystem") {
        // controller not attached: fix cgroup_disable=memory / subtree_control, then restart
    }
    return Err(e);
}

Prevention

When it happens

Trigger: Kernel booted with cgroup_disable=memory; the target cgroup's parent has not enabled +memory in cgroup.subtree_control; containers without the memory controller delegated to them.

Common situations: Hardened kernels disabling the memory controller; systemd slices created without Delegate=memory; restricted container runtimes.

Related errors


AI-assisted analysis of neondatabase/neon@8f60b04da4 (2026-08-16). Data as JSON: /api/errors/56c2031c50dde230. Report an issue: GitHub.