juicedata/juicefs · error
lookup inode for %s: %s
Error message
lookup inode for %s: %s
What it means
`juicefs rmr` removes a subtree directly through the mount's control file instead of walking the FUSE mount. For each argument path it needs the inode of the path's parent directory, obtained via utils.GetFileInode, so it can address the metadata engine. This error is returned when that inode lookup fails, aborting the whole rmr run.
Source
Thrown at cmd/rmr.go:105
} else if runtime.GOOS == "windows" && !utils.IsWinAdminOrElevatedPrivilege() {
logger.Fatalf("Removing files directly requires Administrator or elevated privilege on Windows")
}
flag = 1
}
progress := utils.NewProgress(false)
spin := progress.AddCountSpinner("Removing entries")
for i := 0; i < ctx.Args().Len(); i++ {
path := ctx.Args().Get(i)
p, err := filepath.Abs(path)
if err != nil {
logger.Errorf("abs of %q: %s", path, err)
continue
}
d := filepath.Dir(p)
name := filepath.Base(p)
inode, err := utils.GetFileInode(d)
if err != nil {
return fmt.Errorf("lookup inode for %s: %s", d, err)
}
f, err := openController(d)
if err != nil {
logger.Errorf("Open control file for %q: %s", d, err)
continue
}
wb := utils.NewBuffer(8 + 8 + 1 + uint32(len(name)) + 1 + 1)
wb.Put32(meta.Rmr)
wb.Put32(8 + 1 + uint32(len(name)) + 1 + 1)
wb.Put64(inode)
wb.Put8(uint8(len(name)))
wb.Put([]byte(name))
wb.Put8(flag)
wb.Put8(uint8(numThreads))
_, err = f.Write(wb.Bytes())
if err != nil {
logger.Fatalf("write message: %s", err)
}View on GitHub (pinned to c9a67b23e8)
Solutions
- Verify the path exists and its parent directory is inside a live JuiceFS mount (`ls <dir>` before rmr)
- Check the mount with `juicefs status` / `df` and remount if needed
- Run rmr as a user that can stat the parent directory (root may be needed for --skip-trash)
- Remove the path through the normal filesystem (rm -r) if inode addressing is not required
Example fix
// before juicefs rmr /mnt/jfs/old-data/missing-subdir // error: lookup inode for /mnt/jfs/old-data/missing-subdir: ... // after ls /mnt/jfs/old-data # confirm parent exists on the mounted volume juicefs rmr /mnt/jfs/old-data
Defensive patterns
Strategy: validation
Validate before calling
if _, err := os.Stat(filepath.Dir(path)); err != nil {
log.Fatalf("parent dir not accessible: %v", err)
} Type guard
null
Try / catch
if err := runRmr(path); err != nil {
if strings.Contains(err.Error(), "lookup inode for") {
// path is not on a live JuiceFS mount; fall back to os.RemoveAll
os.RemoveAll(path)
}
} Prevention
- Confirm the target is inside a mounted JuiceFS volume before rmr
- Stat the parent directory in a pre-check
- Keep the mount alive for the duration of the operation
- Use --skip-trash only as root with a verified path
When it happens
Trigger: Running `juicefs rmr <path>` where filepath.Dir(abs(path)) is not a file on a JuiceFS mount — e.g. the parent directory does not exist, the path is on a non-JuiceFS filesystem (GetFileInode cannot resolve an inode), or the mount is broken/unmounted so the statx/stat ioctl that reads the inode fails.
Common situations: Typo in the target path so the parent dir is missing; running rmr against a path outside any JuiceFS mount point; the volume was unmounted between listing and removal; permission problems prevent stat'ing the parent directory.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/72930684ee537562.
Report an issue: GitHub.