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
- Ensure /proc is mounted in the container (docker run defaults do this; check `cat /proc/self/cgroup` works)
- Run the mount with sufficient privileges (privileged container or --device /dev/fuse --cap-add SYS_ADMIN)
- Pre-grant /dev/fuse so grantAccess is unnecessary (e.g. docker run --device /dev/fuse)
- 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
- Run FUSE mounts in privileged containers or with --device /dev/fuse
- Verify /proc is mounted and readable before mounting in containers
- Check seccomp/AppArmor profiles allow procfs reads
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
- read cgroup file
- invalid cgroup entry: %q
- fail to find device cgroup
- read device list file
- invalid device list entry: %q
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/0a7fa0645ea8287e.
Report an issue: GitHub.