lima-vm/lima · error

failed to parse rsync version

Error message

failed to parse rsync version

What it means

rsyncVersion parses the output of the host `rsync --version` with the regex `version (\d+\.\d+\.\d+)` to build a semver. When the output does not contain a recognizable x.y.z version string, it returns "failed to parse rsync version". This guards the rsync-based host<->guest directory sync feature against incompatible or unexpected rsync binaries.

Source

Thrown at cmd/limactl/shell.go:812

	// and `\\server\share\` both reach here. Trim one that leaves a separator
	// behind, which spares the bare roots "/" and `C:\`.
	if trimmed := strings.TrimSuffix(slashed, "/"); strings.Contains(trimmed, "/") {
		slashed = trimmed
	}
	return strings.Count(slashed, "/") + 1
}

func rsyncVersion(ctx context.Context) (*semver.Version, error) {
	out, err := exec.CommandContext(ctx, string(copytool.BackendRsync), "--version").Output()
	if err != nil {
		return nil, err
	}

	// `rsync  version 3.2.7  protocol version 31`
	re := regexp.MustCompile(`version (\d+\.\d+\.\d+)`)
	matches := re.FindSubmatch(out)
	if len(matches) < 2 {
		return nil, errors.New("failed to parse rsync version")
	}
	return semver.NewVersion(string(matches[1]))
}

// Syncs a directory from host to guest and vice-versa. It creates a directory in the guest's home directory and copies the contents of the host's
// current working directory into it. The guest directory paths should be prefixed with `<InstanceName>:` followed by the path.
func rsyncDirectory(ctx context.Context, cmd *cobra.Command, rsync copytool.CopyTool, paths []string) error {
	rsyncCmd, err := rsync.Command(ctx, paths, nil)
	if err != nil {
		return err
	}
	rsyncCmd.Stdout = cmd.OutOrStdout()
	rsyncCmd.Stderr = cmd.OutOrStderr()
	logrus.Debugf("executing rsync: %+v", rsyncCmd.Args)
	return rsyncCmd.Run()
}

func mountDirFromWindowsDir(ctx context.Context, inst *limatype.Instance, dir string) (string, error) {

View on GitHub (pinned to dd909d0973)

Solutions

  1. Run `rsync --version` manually and confirm it prints `rsync version x.y.z`
  2. Check PATH for shadowing: `which -a rsync` and remove/reorder wrappers or shims
  3. Install a standard rsync build (distro package or Homebrew) if missing or nonstandard
  4. If using a wrapper, make it pass through `--version` output unchanged

Example fix

// before: PATH starts with a dir containing an rsync stub script
// after
export PATH=/usr/bin:/bin:$PATH   # or remove the stub so real rsync is found
Defensive patterns

Strategy: validation

Validate before calling

out=$(rsync --version 2>&1 | head -n1) || true
echo "$out" | grep -Eq 'version [0-9]+\.[0-9]+\.[0-9]+' || echo "unexpected rsync at $(command -v rsync): $out" >&2

Try / catch

if ! limactl shell default true 2>&1 | grep -q 'failed to parse rsync version'; then
  :
else
  echo 'Fix rsync install/PATH and retry' >&2; exit 1
fi

Prevention

When it happens

Trigger: shellAction triggers askUserForRsyncBack/rsyncVersion; `rsync --version` output lacks `version <semver>` — e.g. a shell alias/shim intercepting rsync, a wrapper script printing banners, a very old rsync with different version formatting, or an unexpected string on stdout.

Common situations: Rsync replaced by a fake/stub binary (e.g. Homebrew shim, docker in PATH, busybox variant); patched distro builds changing the banner format; PATH shadowing by a wrapper that emits extra output before the version line; rsync not actually installed and error output being parsed.

Understand the failure class

Related errors


AI-assisted analysis of lima-vm/lima@dd909d0973 (2026-09-01). Data as JSON: /api/errors/87633a174366fb75. Report an issue: GitHub.