k3s-io/k3s · critical

failed to find memory cgroup, you may need to add "cgroup_me

Error message

failed to find memory cgroup, you may need to add "cgroup_memory=1 cgroup_enable=memory" to your linux cmdline (/boot/cmdline.txt on a Raspberry Pi)

What it means

During cgroup v1 validation k3s lists active controllers; a missing 'cpuset' controller only logs a warning, but a missing 'memory' controller is fatal because kubelet cannot enforce memory limits/reservations without it. The message includes the remedy because the dominant cause is a kernel booted without the memory cgroup enabled — classically on Raspberry Pi / embedded boards.

Source

Thrown at pkg/cgroups/cgroups_linux.go:49

func validateCgroupsV1() error {
	controllers, err := cgroupsv1.Default()
	if err != nil {
		return err
	}
	m := make(map[string]struct{})
	for _, controller := range controllers {
		name := string(controller.Name())
		m[name] = struct{}{}
	}

	if _, ok := m["cpuset"]; !ok {
		logrus.Warn(`Failed to find cpuset cgroup, you may need to add "cgroup_enable=cpuset" to your linux cmdline (/boot/cmdline.txt on a Raspberry Pi)`)
	}

	if _, ok := m["memory"]; !ok {
		msg := "ailed to find memory cgroup, you may need to add \"cgroup_memory=1 cgroup_enable=memory\" to your linux cmdline (/boot/cmdline.txt on a Raspberry Pi)"
		logrus.Error("F" + msg)
		return errors.New("f" + msg)
	}

	return nil
}

func validateCgroupsV2() error {
	manager, err := cgroupsv2.NewManager("/sys/fs/cgroup", "/", &cgroupsv2.Resources{})
	if err != nil {
		return err
	}
	controllers, err := manager.RootControllers()
	if err != nil {
		return err
	}
	m := make(map[string]struct{})
	for _, controller := range controllers {
		m[controller] = struct{}{}
	}

View on GitHub (pinned to 6ba341e396)

Solutions

  1. Add cgroup_memory=1 cgroup_enable=memory to the kernel command line (/boot/cmdline.txt on Raspberry Pi, GRUB_CMDLINE_LINUX on GRUB systems) and reboot
  2. For LXC: ensure the container's cgroup set includes the memory controller (lxc.apparmor / cgroup config in Proxmox)
  3. Verify after reboot: grep memory /proc/cgroups and cat /proc/cgroups shows the memory controller enabled with non-zero hierarchy
  4. On cgroup v2 hosts this check is bypassed — switching the host to unified v2 also avoids it

Example fix

# before (/boot/cmdline.txt on Raspberry Pi)
console=serial0,115200 root=/dev/mmcblk0p2 rootwait
# -> failed to find memory cgroup

# after
console=serial0,115200 root=/dev/mmcblk0p2 rootwait cgroup_memory=1 cgroup_enable=memory
# then: sudo reboot
Defensive patterns

Strategy: validation

Validate before calling

func memoryCgroupEnabled() bool {
    if cgroups.Mode() == cgroups.Unified { return true } // v2 check differs
    b, err := os.ReadFile("/proc/cgroups")
    if err != nil { return false }
    for _, line := range strings.Split(string(b), "\n") {
        f := strings.Fields(line)
        if len(f) >= 4 && f[0] == "memory" { return f[3] != "0" }
    }
    return false
}
if !memoryCgroupEnabled() { log.Fatal("enable memory cgroup: add cgroup_memory=1 cgroup_enable=memory to kernel cmdline") }

Prevention

When it happens

Trigger: Host booted without cgroup_memory=1 cgroup_enable=memory (Raspberry Pi OS and some ARM boards default to memory cgroups off); lxc/container configs that mask the memory controller from the guest; very old kernels lacking the controller.

Common situations: Raspberry Pi clusters (hence the /boot/cmdline.txt hint); Armbian/embedded SBCs; k3s inside an LXC container where the proxied cgroup set lacks memory; upgrading an old node to a k3s version that validates strictly.

Related errors


AI-assisted analysis of k3s-io/k3s@6ba341e396 (2026-08-15). Data as JSON: /api/errors/8dd9d48cb2396f3b. Report an issue: GitHub.