lima-vm/lima · error

failed to bootstrap LaunchDaemon: %w

Error message

failed to bootstrap LaunchDaemon: %w

What it means

The final step of daemonInstall runs `sudo launchctl bootstrap system <plist>` to load the LaunchDaemon into the system domain; this error wraps that command's failure. The most common cause is launchd error 5 (Bootstrap failed: already loaded) when the daemon is already bootstrapped, or an invalid plist.

Source

Thrown at cmd/limactl/autostart_darwin.go:139

	}
	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)
	_ = runSudo(ctx, "launchctl", "disable", svcTarget)
	if err := runSudo(ctx, "rm", "-f", destPath); err != nil {
		return fmt.Errorf("failed to remove %s: %w", destPath, err)
	}
	logrus.Infof("LaunchDaemon uninstalled for instance %q", instName)
	return nil

View on GitHub (pinned to dd909d0973)

Solutions

  1. Bootout first, then retry: `sudo launchctl bootout system/io.lima-vm.daemon.<instance>` then rerun limactl autostart
  2. Lint the plist: `sudo plutil -lint /Library/LaunchDaemons/io.lima-vm.daemon.<instance>.plist`
  3. Verify the Binary path in the plist exists and is executable (points at the limactl that ran the command)
  4. Check the error output above the message for launchd's numeric error code

Example fix

// before: limactl autostart myinstance --condition=boot  (Bootstrap failed: 5)
// after:  sudo launchctl bootout system/io.lima-vm.daemon.myinstance && limactl autostart myinstance --condition=boot
Defensive patterns

Strategy: retry

Validate before calling

svc=system/io.lima-vm.daemon.<instance>
sudo launchctl print "$svc" >/dev/null 2>&1 && sudo launchctl bootout "$svc"
sudo plutil -lint /Library/LaunchDaemons/io.lima-vm.daemon.<instance>.plist

Try / catch

err := daemonInstall(ctx, inst.Name, inst.Dir, userName, keepAlive)
if err != nil && strings.Contains(err.Error(), "failed to bootstrap LaunchDaemon") {
	// Bootstrap failed is usually 'already bootstrapped': bootout then retry once
	_ = runSudo(ctx, "launchctl", "bootout", "system/io.lima-vm.daemon."+inst.Name)
	err = daemonInstall(ctx, inst.Name, inst.Dir, userName, keepAlive)
}

Prevention

When it happens

Trigger: `limactl autostart <instance> --condition=boot` when `sudo launchctl bootstrap system /Library/LaunchDaemons/io.lima-vm.daemon.<instance>.plist` exits nonzero: daemon already bootstrapped (EEXIST), plist failed plutil lint, program path in plist (limactl binary) missing or not executable, or canceled sudo.

Common situations: Re-running enable on an already-active daemon whose bootout in the same invocation failed silently; limactl was moved/built elsewhere so the Binary path in the plist points to a nonexistent file; SIP/MDM restrictions on system-domain bootstrapping over SSH.

Related errors


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