juicedata/juicefs · error

open %s

Error message

open %s

What it means

grantAccess (called when setting up the FUSE device inside containers) wraps os.Open of /proc/<pid>/cgroup. It reads this file to find the devices cgroup so it can append 'c 10:229 rwm' to devices.allow and grant access to /dev/fuse. Failure to open the procfs cgroup file is wrapped with the path in this message.

Source

Thrown at pkg/fuse/device_linux.go:46

// ensureFuseDev ensures /dev/fuse exists. If not, it will create one
func ensureFuseDev() {
	if _, err := os.Stat("/dev/fuse"); os.IsNotExist(err) {
		// 10, 229 according to https://www.kernel.org/doc/Documentation/admin-guide/devices.txt
		fuse := unix.Mkdev(10, 229)
		if err := syscall.Mknod("/dev/fuse", 0o666|syscall.S_IFCHR, int(fuse)); err != nil {
			logger.Errorf("mknod /dev/fuse: %v", err)
		}
	}
}

// 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" {

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Ensure /proc is mounted in the container (docker run defaults do this; check `cat /proc/self/cgroup` works)
  2. Run the mount with sufficient privileges (privileged container or --device /dev/fuse --cap-add SYS_ADMIN)
  3. Pre-grant /dev/fuse so grantAccess is unnecessary (e.g. docker run --device /dev/fuse)
  4. Check security modules (seccomp/AppArmor/SELinux) logs and relax the profile for procfs reads

Example fix

// before
docker run juicefs/juicefs mount redis://... /mnt/jfs        # no /proc/fuse access
// after
docker run --privileged --device /dev/fuse juicefs/juicefs mount redis://... /mnt/jfs
Defensive patterns

Strategy: fallback

Validate before calling

if _, err := os.ReadFile("/proc/self/cgroup"); err != nil { return fmt.Errorf("procfs unavailable in this environment: %w", err) }
if _, err := os.Stat("/dev/fuse"); err != nil { return fmt.Errorf("/dev/fuse not present: %w", err) }

Try / catch

if err := mount(...); err != nil {
	if strings.Contains(err.Error(), "open /proc/") {
		log.Printf("cannot access cgroup procfs; run privileged or pre-grant /dev/fuse")
	}
}

Prevention

When it happens

Trigger: Mounting JuiceFS via FUSE inside a container/namespace where /proc/<pid>/cgroup cannot be opened: /proc not mounted in the container, procfs hidden, the process exited so the path is gone, or seccomp/AppArmor blocking procfs access.

Common situations: Docker/Kubernetes containers without /proc mounted; running under restricted security profiles (seccomp filters, gVisor) that deny procfs reads; PID-namespace edge cases where the pid lookup fails.

Understand the failure class

Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.

Related errors


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