lima-vm/lima · error

pidfile %#q already exists

Error message

pidfile %#q already exists

What it means

Thrown by `limactl usernet --pidfile PATH` when the given pidfile path already exists. The tool refuses to overwrite an existing pidfile to avoid clobbering a running usernet daemon's PID record; os.Stat is used with errors.Is(err, os.ErrNotExist) so any stat result other than 'not exist' (including real existence or stat errors) triggers this error.

Source

Thrown at cmd/limactl/usernet.go:44

	}
	hostagentCommand.Flags().StringP("pidfile", "p", "", "Write PID to file")
	hostagentCommand.Flags().StringP("endpoint", "e", "", "Exposes usernet API(s) on this endpoint")
	hostagentCommand.Flags().String("listen-qemu", "", "Listen for QMEU connections")
	hostagentCommand.Flags().String("listen", "", "Listen on a Unix socket and receive Bess-compatible FDs as SCM_RIGHTS messages")
	hostagentCommand.Flags().String("subnet", "192.168.5.0/24", "Sets subnet value for the usernet network")
	hostagentCommand.Flags().Int("mtu", 1500, "mtu")
	hostagentCommand.Flags().StringToString("leases", nil, "Pass default static leases for startup. Eg: '192.168.104.1=52:55:55:b3:bc:d9,192.168.104.2=5a:94:ef:e4:0c:df' ")
	return hostagentCommand
}

func usernetAction(cmd *cobra.Command, _ []string) error {
	pidfile, err := cmd.Flags().GetString("pidfile")
	if err != nil {
		return err
	}
	if pidfile != "" {
		if _, err := os.Stat(pidfile); !errors.Is(err, os.ErrNotExist) {
			return fmt.Errorf("pidfile %#q already exists", pidfile)
		}
		if err := os.WriteFile(pidfile, []byte(strconv.Itoa(os.Getpid())+"\n"), 0o644); err != nil {
			return err
		}
		defer os.RemoveAll(pidfile)
	}
	endpoint, err := cmd.Flags().GetString("endpoint")
	if err != nil {
		return err
	}
	qemuSocket, err := cmd.Flags().GetString("listen-qemu")
	if err != nil {
		return err
	}
	fdSocket, err := cmd.Flags().GetString("listen")
	if err != nil {
		return err
	}

View on GitHub (pinned to dd909d0973)

Solutions

  1. Verify no usernet process is running (check the PID in the existing pidfile with `ps -p $(cat /path/pid)`), then delete the stale pidfile and retry.
  2. If a process is still running, kill it cleanly or use a different pidfile path.
  3. Choose a unique pidfile path per usernet invocation to avoid collisions.

Example fix

// before
limactl usernet --pidfile /tmp/lima-usernet.pid
// pidfile "/tmp/lima-usernet.pid" already exists
// after
ps -p $(cat /tmp/lima-usernet.pid) || rm /tmp/lima-usernet.pid
limactl usernet --pidfile /tmp/lima-usernet.pid
Defensive patterns

Strategy: validation

Validate before calling

if pidfile != "" {
    if _, err := os.Stat(pidfile); err == nil {
        // decide: reuse, kill the old process, or pick another path
        pid, _ := os.ReadFile(pidfile)
        fmt.Printf("pidfile held by pid %s\n", pid)
        os.Exit(1)
    }
}

Try / catch

if err := usernetCmd.Execute(); err != nil && strings.Contains(err.Error(), "already exists") {
    // remove stale pidfile after confirming the process is gone, then retry once
}

Prevention

When it happens

Trigger: Running `limactl usernet --pidfile /path/pid` when /path/pid exists from a previous run that was not cleaned up, or when another usernet instance is currently running and holding that pidfile.

Common situations: A previous usernet process crashed without its `defer os.RemoveAll(pidfile)` running (SIGKILL, machine reboot); two terminal sessions starting usernet with the same pidfile path; a stale pidfile left behind after an abnormal shutdown.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


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