juicedata/juicefs · error

the clone DST path should not be under the SRC path

Error message

the clone DST path should not be under the SRC path

What it means

Cloning a directory into a location under itself would create an infinite recursion (a directory containing a clone of itself). The command detects this by checking whether the absolute DST path is prefixed by the cleaned absolute SRC path plus '/', and rejects it.

Source

Thrown at cmd/clone.go:106

	}
	dstAbsPath, err := filepath.Abs(dst)
	if err != nil {
		return fmt.Errorf("abs of %s: %s", dst, err)
	}

	srcMp, err := findMountpoint(srcAbsPath)
	if err != nil {
		return err
	}
	dstMp, err := findMountpoint(filepath.Dir(dstAbsPath))
	if err != nil {
		return err
	}
	if srcMp != dstMp {
		return fmt.Errorf("the clone DST path should be at the same mount point as the SRC path")
	}
	if strings.HasPrefix(dstAbsPath, path.Clean(srcAbsPath)+"/") {
		return fmt.Errorf("the clone DST path should not be under the SRC path")
	}

	dstParent := filepath.Dir(dstAbsPath)
	dstName := filepath.Base(dstAbsPath)
	dstParentIno, err := utils.GetFileInode(dstParent)
	if err != nil {
		return fmt.Errorf("lookup inode for %s: %s", dstParent, err)
	}
	var cmode uint8
	umask := utils.GetUmask()
	if ctx.Bool("preserve") || runtime.GOOS == "windows" {
		cmode |= meta.CLONE_MODE_PRESERVE_ATTR
	}
	threads := ctx.Int("threads")
	if threads < 1 {
		threads = 1
	} else if threads > 255 {
		threads = 255

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Choose a DST outside the SRC tree, e.g. a sibling: `juicefs clone /mnt/jfs/dir1 /mnt/jfs/dir1-copy`
  2. Do not append the new name under SRC when scripting; join the SRC parent with the new name instead
  3. If the paths only look nested via symlinks/../components, re-run with fully resolved absolute paths so the prefix check matches your intent

Example fix

// before
juicefs clone /mnt/jfs/dir1 /mnt/jfs/dir1/clone  # error
// after
juicefs clone /mnt/jfs/dir1 /mnt/jfs/dir1-clone
Defensive patterns

Strategy: validation

Validate before calling

cleanSrc := filepath.Clean(absSrc)
if strings.HasPrefix(absDst, cleanSrc+string(os.PathSeparator)) {
    return errors.New("DST must not be inside SRC")
}

Try / catch

if err := runClone(src, dst); strings.Contains(err.Error(), "under the SRC path") {
    dst = filepath.Join(filepath.Dir(src), filepath.Base(dst))
    err = runClone(src, dst)
}

Prevention

When it happens

Trigger: Running `juicefs clone /mnt/jfs/dir1 /mnt/jfs/dir1/copy` — DST lies inside the SRC directory tree. Also triggered when DST is a subdirectory deeper under SRC, e.g. cloning dir1 into dir1/sub/newname.

Common situations: User standing inside the source directory uses a relative DST that resolves under SRC (`cd /mnt/jfs/dir1 && juicefs clone .. copy` resolves differently, but `juicefs clone . ./copy` or `juicefs clone dir1 dir1/clone`); scripting that builds DST by joining SRC with a name.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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