rqlite/rqlite · error

destination already exists

Error message

destination already exists

What it means

CopyDir refuses to run when the destination path already exists (os.Stat succeeds), since the copy is atomic via rename and would otherwise clobber existing data. The caller must remove or choose a new destination first.

Source

Thrown at internal/fsutil/copy.go:66

// interrupted copy to the same destination is removed first.
func CopyDir(src string, dst string) error {
	src = filepath.Clean(src)
	dst = filepath.Clean(dst)

	si, err := os.Stat(src)
	if err != nil {
		return err
	}
	if !si.IsDir() {
		return fmt.Errorf("source is not a directory")
	}

	_, err = os.Stat(dst)
	if err != nil && !os.IsNotExist(err) {
		return err
	}
	if err == nil {
		return fmt.Errorf("destination already exists")
	}

	// Stage the copy in a temporary directory next to the destination, clearing
	// out any remains of an earlier interrupted copy. The deferred removal is a
	// no-op once the rename below has succeeded.
	tmp := dst + tmpSuffix
	if err := os.RemoveAll(tmp); err != nil {
		return err
	}
	defer os.RemoveAll(tmp)

	if err := copyDir(src, tmp); err != nil {
		return err
	}
	if err := os.Rename(tmp, dst); err != nil {
		return err
	}
	return SyncDirParentMaybe(dst)

View on GitHub (pinned to 7586a4d1bd)

Solutions

  1. Remove the existing destination directory if it is safe to overwrite
  2. Choose a fresh destination path
  3. Clean up leftovers from a previous failed copy before retrying
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at internal/fsutil/copy.go:66 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of rqlite/rqlite@7586a4d1bd (2026-09-03). Data as JSON: /api/errors/214924d718b45700. Report an issue: GitHub.