lima-vm/lima · error

failed to install plist to %s: %w

Error message

failed to install plist to %s: %w

What it means

After staging the plist, daemonInstall copies it into /Library/LaunchDaemons via `sudo install -m 644`; this error wraps that sudo command's failure. Since the destination requires root, the copy fails when sudo is denied/canceled or the destination path is bad.

Source

Thrown at cmd/limactl/autostart_darwin.go:133

		return fmt.Errorf("failed to render daemon plist: %w", err)
	}

	tmp, err := os.CreateTemp("", "io.lima-vm.daemon.*.plist")
	if err != nil {
		return fmt.Errorf("failed to create temp file: %w", err)
	}
	defer os.Remove(tmp.Name())
	if _, err := tmp.Write(content); err != nil {
		return fmt.Errorf("failed to write temp plist: %w", err)
	}
	tmp.Close()

	destPath := launchd.GetDaemonPlistPath(instName)
	svcTarget := "system/" + launchd.DaemonServiceNameFrom(instName)

	_ = runSudo(ctx, "launchctl", "bootout", svcTarget)
	if err := runSudo(ctx, "install", "-m", "644", tmp.Name(), destPath); err != nil {
		return fmt.Errorf("failed to install plist to %s: %w", destPath, err)
	}
	if err := runSudo(ctx, "launchctl", "enable", svcTarget); err != nil {
		return fmt.Errorf("failed to enable LaunchDaemon: %w", err)
	}
	if err := runSudo(ctx, "launchctl", "bootstrap", "system", destPath); err != nil {
		return fmt.Errorf("failed to bootstrap LaunchDaemon: %w", err)
	}

	logrus.Infof("LaunchDaemon installed for instance %q (runs as %q at boot)", instName, userName)
	logrus.Infof("Plist: %s", destPath)
	return nil
}

func daemonUninstall(ctx context.Context, instName string) error {
	svcTarget := "system/" + launchd.DaemonServiceNameFrom(instName)
	destPath := launchd.GetDaemonPlistPath(instName)

	_ = runSudo(ctx, "launchctl", "bootout", svcTarget)

View on GitHub (pinned to dd909d0973)

Solutions

  1. Rerun the command and enter the sudo password when prompted
  2. Verify the account is an administrator: `groups` should include `admin`
  3. Manually confirm write access: `ls -ld /Library/LaunchDaemons`
  4. If a conflicting plist exists, remove it first: `sudo rm /Library/LaunchDaemons/io.lima-vm.daemon.<instance>.plist`

Example fix

// before: limactl autostart myinstance --condition=boot  (sudo prompt canceled)
// after:  sudo -v && limactl autostart myinstance --condition=boot
Defensive patterns

Strategy: try-catch

Validate before calling

sudo -v 2>/dev/null || { echo "sudo unavailable: need admin rights"; exit 1; }
ls -ld /Library/LaunchDaemons >/dev/null || exit 1

Try / catch

err := daemonInstall(ctx, inst.Name, inst.Dir, userName, keepAlive)
if err != nil {
	if strings.Contains(err.Error(), "failed to install plist") {
		logrus.Error("Could not write to /Library/LaunchDaemons: confirm admin rights and accept the sudo prompt")
		return
	}
	panic(err)
}

Prevention

When it happens

Trigger: `limactl autostart <instance> --condition=boot` on macOS when `sudo install -m 644 <tmp> /Library/LaunchDaemons/io.lima-vm.daemon.<instance>.plist` exits nonzero: user canceled the sudo password prompt, user lacks sudo rights, or destination directory missing/odd permissions.

Common situations: Non-admin macOS account without sudo privileges; sudo timeout while the user is not at the terminal; MDM policies blocking writes to /Library/LaunchDaemons; stale LaunchDaemon file owned by another user blocking install.

Related errors


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