{"record":{"id":"c61218cc072b1abe","repo":"lima-vm/lima","slug":"s-daemon-for-q-network-failed-to-start-after-d","errorCode":null,"errorMessage":"%s daemon for %#q network failed to start after %d attempts: %w%s","messagePattern":"(.+?) daemon for %#q network failed to start after (.+?) attempts: %w(.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/networks/reconcile/reconcile.go","lineNumber":318,"sourceCode":"\t\t\treturn err // infrastructure failure (sudo/exec) — not transient\n\t\t}\n\t\terr = waitForDaemon(ctx, cmd, pidFile, startTimeout)\n\t\tif err == nil {\n\t\t\treturn nil\n\t\t}\n\t\t// Only an early exit (the transient XPC race) is retried; everything else\n\t\t// is surfaced immediately.\n\t\tif _, ok := errors.AsType[*daemonExitedError](err); !ok {\n\t\t\t// A stuck (still-running) daemon gets its stderr appended; PID-read and\n\t\t\t// context errors propagate as-is.\n\t\t\tif _, ok := errors.AsType[*daemonStuckError](err); ok {\n\t\t\t\treturn fmt.Errorf(\"%s daemon for %#q network %w%s\", daemon, name, err, stderrHint(stderrLog))\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\t\tlastErr = err // process exited early — retry\n\t}\n\treturn fmt.Errorf(\"%s daemon for %#q network failed to start after %d attempts: %w%s\",\n\t\tdaemon, name, maxAttempts, lastErr, stderrHint(stderrLog))\n}\n\n// waitForDaemon waits until the daemon writes its PID file (success), exits without\n// one (returns *daemonExitedError so the caller can retry), or stays alive past\n// timeout without a PID file (returns *daemonStuckError). A stuck or cancelled\n// process is killed and reaped.\nfunc waitForDaemon(ctx context.Context, cmd *exec.Cmd, pidFile string, timeout time.Duration) error {\n\twaitCh := make(chan error, 1)\n\tgo func() { waitCh <- cmd.Wait() }()\n\n\ttimer := time.NewTimer(timeout)\n\tdefer timer.Stop()\n\tticker := time.NewTicker(500 * time.Millisecond)\n\tdefer ticker.Stop()\n\n\tfor {\n\t\tready, err := pidFileWritten(pidFile)","sourceCodeStart":300,"sourceCodeEnd":336,"githubUrl":"https://github.com/lima-vm/lima/blob/dd909d0973cd84fa35f9e1693181b4585ea616c1/pkg/networks/reconcile/reconcile.go#L300-L336","documentation":"The network daemon exited before writing its PID file on every one of the 5 retry attempts (with 1s/2s/4s/8s backoff). This retry loop exists specifically for the transient macOS VMNET_FAILURE XPC race with com.apple.NetworkSharing at boot; exhausting all attempts means the daemon is deterministically failing. The daemon's stderr (or log path) is appended to explain why it exits.","triggerScenarios":"startDaemonWithRetry observes *daemonExitedError five consecutive times — the daemon binary starts and exits each time before creating its PID file, e.g. socket_vmnet crashing on VMNET_FAILURE, bad arguments, missing network device, or a genuinely broken install.","commonSituations":"macOS right after boot when the race is not transient (broken socket_vmnet), socket_vmnet version mismatch with the generated sudoers config, the configured switch device (e.g. bridge100) not existing, or the daemon lacking permission to open the VMNET interface.","solutions":["Inspect the daemon stderr in the message (or the log file under ~/.lima/networks) for the concrete exit reason","Verify socket_vmnet is installed and current: brew install/reinstall socket_vmnet","Check networks.yaml: socketVMNet path and the network switch device must exist on this host","Reboot the Mac so com.apple.NetworkSharing is fully initialized, then retry","Regenerate the sudoers file if socket_vmnet was upgraded: limactl sudoers | sudo tee /etc/sudoers.d/lima"],"exampleFix":"// before\nlimactl start  # fails after 5 attempts: socket_vmnet VMNET_FAILURE\n// after\nbrew reinstall socket_vmnet\nlimactl sudoers | sudo tee /etc/sudoers.d/lima\nlimactl start","handlingStrategy":"retry","validationCode":"if _, err := os.Stat(socketVMNetPath); err != nil {\n    return fmt.Errorf(\"socket_vmnet not installed at %s: %w\", socketVMNetPath, err)\n}\nif err := exec.Command(socketVMNetPath, \"--version\").Run(); err != nil {\n    return fmt.Errorf(\"socket_vmnet binary broken: %w\", err)\n}","typeGuard":"func isDaemonExitedError(err error) bool {\n    var e *daemonExitedError\n    return errors.As(err, &e)\n}","tryCatchPattern":"if err := startNetwork(); err != nil {\n    if strings.Contains(err.Error(), \"failed to start after\") {\n        // deterministic daemon failure: check stderr hint, reinstall socket_vmnet\n    }\n    return err\n}","preventionTips":["Reinstall socket_vmnet after Homebrew upgrades and regenerate the sudoers file","Reboot after macOS upgrades so com.apple.NetworkSharing is healthy","Verify the network device in networks.yaml exists on the host","Read the appended stderr hint in the error for the real exit reason"],"tags":["network","socket-vmnet","daemon-startup","retry-exhausted","macos"],"backgroundTag":"daemon-start-failed","analyzedSha":"dd909d0973cd84fa35f9e1693181b4585ea616c1","analyzedAt":"2026-09-01T14:24:59.842Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}