juicedata/juicefs · error
lookup inode for %s: %s
Error message
lookup inode for %s: %s
What it means
After resolving the absolute path, clone reads the source file's inode with utils.GetFileInode(srcPath). "lookup inode for %s: %s" means that call failed — typically the source path does not exist or is not a regular file/directory on which the ioctl-based inode lookup works.
Source
Thrown at cmd/clone.go:74
&cli.IntFlag{
Name: "threads",
Value: meta.CLONE_DEFAULT_CONCURRENCY,
Usage: "number of concurrent workers for cloning directories",
},
},
}
}
func clone(ctx *cli.Context) error {
setup(ctx, 2)
srcPath := ctx.Args().Get(0)
srcAbsPath, err := filepath.Abs(srcPath)
if err != nil {
return fmt.Errorf("abs of %s: %s", srcPath, err)
}
srcIno, err := utils.GetFileInode(srcPath)
if err != nil {
return fmt.Errorf("lookup inode for %s: %s", srcPath, err)
}
srcParentIno, err := utils.GetFileInode(filepath.Dir(srcAbsPath))
if err != nil {
return fmt.Errorf("lookup inode for %s: %s", filepath.Dir(srcAbsPath), err)
}
dst := ctx.Args().Get(1)
if strings.HasSuffix(dst, string(filepath.Separator)) {
dst = filepath.Join(dst, filepath.Base(srcPath))
}
if _, err := os.Stat(dst); err == nil {
return fmt.Errorf("%s already exists", dst)
} else if !os.IsNotExist(err) {
return fmt.Errorf("stat %s: %s", dst, err)
}
dstAbsPath, err := filepath.Abs(dst)
if err != nil {
return fmt.Errorf("abs of %s: %s", dst, err)
}View on GitHub (pinned to c9a67b23e8)
Solutions
- Verify the source path exists (ls) and is spelled correctly.
- Ensure the source lives on a JuiceFS mount — clone only works for JuiceFS files.
- Check read/stat permissions on the source path.
- Re-check the source wasn't concurrently removed (especially in scripts).
Example fix
# before juicefs clone meta.sqlite3:0 /mnt/jfs/missing-file /dst # after ls /mnt/jfs/missing-file # confirm it exists first juicefs clone meta.sqlite3:0 /mnt/jfs/real-file /dst
Defensive patterns
Strategy: validation
Validate before calling
func srcExists(p string) bool {
fi, err := os.Stat(p)
return err == nil && (fi.Mode().IsRegular() || fi.IsDir())
}
// check srcExists(src) before running clone Try / catch
if err := clone(ctx); err != nil && strings.HasPrefix(err.Error(), "lookup inode for") {
log.Printf("source %s not clonable (missing or not on JuiceFS): %v", ctx.Args().Get(0), err)
} Prevention
- Confirm the source exists and is inside the JuiceFS mount before cloning
- Remember clone relies on inode ioctls — other filesystems will fail the lookup
- In pipelines, re-stat the source right before cloning to catch concurrent deletion
When it happens
Trigger: Calling `juicefs clone <src> <dst>` where src doesn't exist, is a dangling symlink, resides outside a JuiceFS mount (GetFileInode uses FS_IOC_FIEMAP/inode ioctls unsupported by other filesystems), or the path lacks permission to be stat'd.
Common situations: Typo'd source path, cloning a file from a non-JuiceFS filesystem (ext4/NFS won't report the expected inode via the ioctl), cloning after the source was deleted by another process, or permission issues on the path.
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/516a5be9e98816b6.
Report an issue: GitHub.