lima-vm/lima · critical
host agent process has exited: %w
Error message
host agent process has exited: %w
What it means
lima wraps the hostagent process wait error when the hostagent process terminates while limactl is still watching it. In StartWithPaths, two channels race: watchErrCh (event watching result) and waitErrCh (process exit). If waitErrCh fires first, the hostagent process exited prematurely, and the underlying wait error is wrapped with %w so root causes (signal, exec failure) are preserved.
Source
Thrown at pkg/instance/start.go:342
}()
waitErrCh := make(chan error)
if haCmd != nil {
go func() {
waitErrCh <- haCmd.Wait()
close(waitErrCh)
}()
} else {
defer close(waitErrCh)
}
select {
case watchErr := <-watchErrCh:
// watchErr can be nil
return watchErr
// leave the hostagent process running
case waitErr := <-waitErrCh:
// waitErr should not be nil
return fmt.Errorf("host agent process has exited: %w", waitErr)
}
}
func Start(ctx context.Context, inst *limatype.Instance, launchHostAgentForeground, showProgress bool) error {
return StartWithPaths(ctx, inst, launchHostAgentForeground, showProgress, "", "")
}
func waitHostAgentStart(_ context.Context, haPIDPath, haStderrPath string) error {
begin := time.Now()
deadlineDuration := 5 * time.Second
deadline := begin.Add(deadlineDuration)
for {
if _, err := os.Stat(haPIDPath); !errors.Is(err, os.ErrNotExist) {
return nil
}
if time.Now().After(deadline) {
return fmt.Errorf("hostagent (%#q) did not start up in %v (hint: see %#q)", haPIDPath, deadlineDuration, haStderrPath)
}View on GitHub (pinned to dd909d0973)
Solutions
- Inspect the hostagent log at ~/.lima/<instance>/ha.stderr.log for the actual crash cause
- Validate lima.yaml with `limactl start --print` or `limactl validate` before starting
- Remove stale instance state with `limactl delete -f <instance>` and recreate
- Upgrade/reinstall lima so the hostagent binary matches limactl version
Example fix
// before
err := lima.Start(ctx, inst) // opaque: host agent process has exited: exit status 2
// after
if err != nil {
logrus.Debugf("ha.stderr: %s", readHAStderr(inst))
return fmt.Errorf("start failed: %w", err)
} Defensive patterns
Strategy: try-catch
Validate before calling
// before start
if _, err := os.Stat(filepath.Join(home, ".lima", instName, "lima.yaml")); err != nil { recreate() }
out, err := exec.Command("limactl", "validate", cfgPath).CombinedOutput()
if err != nil { log.Fatalf("invalid config: %s", out) } Type guard
var waitErr interface{ Unwrap() error }
if errors.As(err, &target) { /* inspect wrapped exec.ExitError */ }
var ee *exec.ExitError
if errors.As(err, &ee) { code := ee.ExitCode() } Try / catch
err := lima.Start(ctx, inst)
if err != nil && strings.Contains(err.Error(), "host agent process has exited") {
log := filepath.Join(home, ".lima", inst.Name, "ha.stderr.log")
b, _ := os.ReadFile(log)
return fmt.Errorf("hostagent crashed: %w\nha.stderr:\n%s", err, b)
} Prevention
- Validate lima.yaml before every start
- Keep limactl and guestagent binaries from the same release
- Watch ha.stderr.log on failure
- Avoid killing processes named lima/hostagent during startup
When it happens
Trigger: Running `limactl start` when the hostagent binary crashes or is killed before it finishes setting up; the waitHostAgent goroutine returns a non-nil waitErr that wins the select over watchErrCh.
Common situations: Hostagent panics on malformed lima.yaml, missing dependencies on the host, OOM-kill of the hostagent process, or incompatible lima version after upgrade leaving stale state in ~/.lima/<instance>.
Related errors
- exiting, status=%+v (hint: see %#q)
- did not receive an event with the `running` status
- another hostagent may already be running with pid %d (pidfil
- failed to determine if another hostagent is running: %w
- failed to run %v: %w; stderr=%#q
AI-assisted analysis of lima-vm/lima@dd909d0973 (2026-09-01).
Data as JSON: /api/errors/3ae171825916881b.
Report an issue: GitHub.