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

  1. Verify the source path exists (ls) and is spelled correctly.
  2. Ensure the source lives on a JuiceFS mount — clone only works for JuiceFS files.
  3. Check read/stat permissions on the source path.
  4. 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

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.