juicedata/juicefs · error

read cgroup file

Error message

read cgroup file

What it means

Wraps bufio.Scanner errors while line-scanning /proc/<pid>/cgroup in grantAccess, which searches for the 'devices' cgroup controller to grant FUSE device access. The scanner error is typically read I/O failure on procfs rather than a parse problem (malformed lines produce the separate 'invalid cgroup entry' error).

Source

Thrown at pkg/fuse/device_linux.go:54

		}
	}
}

// grantAccess appends 'c 10:229 rwm' to devices.allow
func grantAccess() error {
	pid := os.Getpid()
	cgroupPath := fmt.Sprintf("/proc/%d/cgroup", pid)
	cgroupFile, err := os.Open(cgroupPath)
	if err != nil {
		return errors.Wrapf(err, "open %s", cgroupPath)
	}
	defer cgroupFile.Close()

	cgroupScanner := bufio.NewScanner(cgroupFile)
	var deviceCgroup string
	for cgroupScanner.Scan() {
		if err := cgroupScanner.Err(); err != nil {
			return errors.Wrap(err, "read cgroup file")
		}
		var (
			text  = cgroupScanner.Text()
			parts = strings.SplitN(text, ":", 3)
		)
		if len(parts) < 3 {
			return errors.Errorf("invalid cgroup entry: %q", text)
		}

		if parts[1] == "devices" {
			deviceCgroup = parts[2]
		}
	}

	if len(deviceCgroup) == 0 {
		return errors.Errorf("fail to find device cgroup")
	}

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Retry the mount — transient procfs read errors often disappear
  2. Verify `cat /proc/self/cgroup` works in the same environment; if not, fix the runtime/security profile
  3. Grant /dev/fuse externally (--device /dev/fuse, privileged mode) so grantAccess is skipped
  4. If cgroup output is unusually large, run in a runtime that exposes standard procfs behavior

Example fix

// before
# sandboxed runtime with broken procfs
kata-runtime run ... juicefs mount redis://... /mnt/jfs
// after
# standard runc container with device granted
docker run --device /dev/fuse --cap-add SYS_ADMIN juicefs/juicefs mount redis://... /mnt/jfs
Defensive patterns

Strategy: fallback

Validate before calling

data, err := os.ReadFile("/proc/self/cgroup")
if err != nil { return fmt.Errorf("cannot read cgroup info: %w", err) }
if len(data) == 0 || len(data) > 1<<20 { return fmt.Errorf("unexpected cgroup file size: %d", len(data)) }

Try / catch

if err := mount(...); err != nil {
	if strings.Contains(err.Error(), "read cgroup file") {
		log.Printf("procfs read failed in this runtime; pre-grant /dev/fuse or use a standard runtime")
	}
}

Prevention

When it happens

Trigger: Mounting via FUSE in a container where reading /proc/<pid>/cgroup fails mid-scan: procfs read returning EIO due to kernel/security oddities, file larger than the scanner buffer with no token (rare for cgroup files), or kernel errors under heavy cgroup v2 hierarchies.

Common situations: gVisor/Kata or other sandboxed runtimes whose procfs emulation errors on reads; unusual kernel instrumentation; very long cgroup v2 paths exceeding the default 64KB bufio.Scanner token limit.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06). Data as JSON: /api/errors/e300e220e94dfdae. Report an issue: GitHub.