k3s-io/k3s · critical

unhandled cgroup mode

Error message

unhandled cgroup mode

What it means

At startup k3s validates the host cgroup layout using containerd's cgroups.Mode(): Unified (v2 only), Legacy (v1 only), or Hybrid (v1 + v2 mounted). Any other value — practically the Unavailable mode returned when the cgroup filesystem cannot be detected — falls through to this error. It aborts startup because kubelet/cadvisor cannot manage resources without a known cgroup hierarchy.

Source

Thrown at pkg/cgroups/cgroups_linux.go:27

	"os"
	"path/filepath"
	"strings"

	cgroups "github.com/containerd/cgroups/v3"
	cgroupsv1 "github.com/containerd/cgroups/v3/cgroup1"
	cgroupsv2 "github.com/containerd/cgroups/v3/cgroup2"
	"github.com/k3s-io/k3s/pkg/version"
	"github.com/sirupsen/logrus"
)

func Validate() error {
	switch cgroups.Mode() {
	case cgroups.Unified:
		return validateCgroupsV2()
	case cgroups.Legacy, cgroups.Hybrid:
		return validateCgroupsV1()
	default:
		return errors.New("unhandled cgroup mode")
	}
}

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)`)
	}

View on GitHub (pinned to 6ba341e396)

Solutions

  1. On bare metal/VMs, ensure the host boots with a standard cgroup setup (cgroup v2 unified or legacy v1) so /sys/fs/cgroup is mounted
  2. For k3s-in-container, run the container with host cgroup visibility (e.g. privileged with cgroup mounts) or use k3d/docker's --privileged with proper volume mounts
  3. Check `stat -fc %T /sys/fs/cgroup` (expect cgroup2fs or tmpfs) and mount the cgroup filesystem if absent

Example fix

# before
mount | grep cgroup # empty -> unhandled cgroup mode

# after (inside a container host namespace)
mount -t cgroup2 none /sys/fs/cgroup
systemctl restart k3s
Defensive patterns

Strategy: validation

Validate before calling

func cgroupModeSupported() error {
    switch cgroups.Mode() {
    case cgroups.Unified, cgroups.Legacy, cgroups.Hybrid:
        return nil
    default:
        return fmt.Errorf("cgroup mode unavailable (Mode=%d); mount /sys/fs/cgroup properly before starting k3s", cgroups.Mode())
    }
}

Prevention

When it happens

Trigger: Running k3s in an environment where /sys/fs/cgroup is missing, not mounted, or unreadable: minimal VMs/initramfs, misconfigured containers running k3s-in-docker with cgroup namespaces hiding the hierarchy, or unusual runtimes.

Common situations: k3s inside a Docker/Podman container started without a proper cgroup mount; stripped cloud images/WSL2 setups where cgroup detection fails; nested virtualization with restricted /sys exposure.

Related errors


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