lima-vm/lima · error

failed to read PID file %#q: %w

Error message

failed to read PID file %#q: %w

What it means

Lima could not read the network daemon's PID file while polling for daemon readiness. Unlike 'file not yet created' (which just means not-ready), a read error such as a corrupt or unreadable PID file is treated as non-transient and aborts startup immediately so it is not mistaken for a slow daemon.

Source

Thrown at pkg/networks/reconcile/reconcile.go:380

			}
			return &daemonExitedError{err: waitErr}
		case <-timer.C:
			_ = cmd.Process.Kill()
			<-waitCh
			return &daemonStuckError{timeout: timeout}
		case <-ticker.C:
			// re-check the PID file on the next loop iteration
		}
	}
}

// pidFileWritten reports whether the daemon has written a valid PID file. A read
// error (e.g. a corrupt or unreadable PID file) is non-transient and is returned so
// the caller can fail fast rather than mistake it for a daemon that is slow to start.
func pidFileWritten(pidFile string) (bool, error) {
	pid, err := store.ReadPIDFile(pidFile)
	if err != nil {
		return false, fmt.Errorf("failed to read PID file %#q: %w", pidFile, err)
	}
	return pid != 0, nil
}

// stderrHint returns the daemon's stderr (or a pointer to the log) to append to errors.
func stderrHint(stderrLog string) string {
	if b, err := os.ReadFile(stderrLog); err == nil && len(b) > 0 {
		return fmt.Sprintf(" (stderr: %s)", strings.TrimSpace(string(b)))
	}
	return fmt.Sprintf(" (check %#q)", stderrLog)
}

func stopNetwork(ctx context.Context, cfg *networks.Config, name string) error {
	logrus.Debugf("Make sure %#q network is stopped", name)
	// Handle usernet first without sudo requirements
	isUsernet, err := cfg.Usernet(name)
	if err != nil {
		return err

View on GitHub (pinned to dd909d0973)

Solutions

  1. Delete the corrupt PID file shown in the message and retry limactl start
  2. Ensure no other Lima instance/process is concurrently writing the same PID file
  3. Check permissions on the file and its parent directory (~/.lima/networks)
  4. Set a distinct LIMA_HOME if multiple Lima versions share the same instance dir

Example fix

// before: corrupt PID file
rm ~/.lima/networks/lima-shared_pid
// after: clean state, retry
limactl start
Defensive patterns

Strategy: validation

Validate before calling

func validPIDFile(path string) bool {
    b, err := os.ReadFile(path)
    if err != nil { return true } // missing is fine (not ready yet)
    var pid int
    _, err = fmt.Sscanf(strings.TrimSpace(string(b)), "%d", &pid)
    return err == nil && pid > 0
}

Try / catch

if err := startNetwork(); err != nil {
    if strings.Contains(err.Error(), "failed to read PID file") {
        os.Remove(pidFilePath) // clear corrupt file, retry
    }
}

Prevention

When it happens

Trigger: pidFileWritten calls store.ReadPIDFile(pidFile) during waitForDaemon polling and gets an error other than not-exists-yet — e.g. a malformed/corrupt PID file, permission denied on the file, or a PID file containing invalid content.

Common situations: A previous crashed run left a truncated or garbage PID file under ~/.lima/networks, the file was edited by hand, or permission changes on ~/.lima make the file unreadable.

Related errors


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