lima-vm/lima · error

failed to run %v: %w; stderr=%#q

Error message

failed to run %v: %w; stderr=%#q

What it means

startAndStreamKubectl launches a long-running kubectl command with StdoutPipe and streams its output; if cmd.Start fails (or the subsequent cmd.Wait fails, which is wrapped with the same message), this error includes cmd.Args and whatever stderr was captured. Note that stderr is captured into a buffer that is only filled during the run, so on Start failure it is typically empty.

Source

Thrown at pkg/guestagent/kubernetesservice/kubernetesservice.go:136

		return fmt.Errorf("failed to run %v: %w; stdout=%#q, stderr=%#q", cmd.Args, err, stdout.String(), stderr.String())
	}
	if strings.TrimSpace(stdout.String()) != "yes" {
		return fmt.Errorf("failed to run %v: expected `yes`, got %#q", cmd.Args, stdout.String())
	}
	return nil
}

func (s *ServiceWatcher) startAndStreamKubectl(cmd *exec.Cmd) error {
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		return err
	}

	var stderr bytes.Buffer
	cmd.Stderr = &stderr

	if err := cmd.Start(); err != nil {
		return fmt.Errorf("failed to run %v: %w; stderr=%#q", cmd.Args, err, stderr.String())
	}

	readErr := s.readKubectlStream(stdout)
	waitErr := cmd.Wait()
	if waitErr != nil {
		waitErr = fmt.Errorf("failed to run %v: %w; stderr=%#q", cmd.Args, waitErr, stderr.String())
	}
	return errors.Join(readErr, waitErr)
}

// readKubectlStream reads kubectl JSON watch events from r and updates the internal
// services map. The stream is newline-delimited JSON objects representing "WatchEvent".
func (s *ServiceWatcher) readKubectlStream(r io.Reader) error {
	scanner := bufio.NewScanner(r)
	// increase buffer in case of large JSON objects
	const maxBuf = 10 * units.MiB
	buf := make([]byte, 0, 64*units.KiB)
	scanner.Buffer(buf, maxBuf)

View on GitHub (pinned to dd909d0973)

Solutions

  1. Check that the kubectl binary in cmd.Args exists and is executable inside the guest.
  2. Inspect the stderr=... portion (on Wait failures) for kubectl's own error output.
  3. Verify the kubeconfig remains valid for the duration of streaming (`kubectl auth can-i get services`).
  4. If the error appears during instance shutdown, it is expected context cancellation and can be ignored.

Example fix

// before
exec.Command("kubectl-not-installed", "get", "services", "--watch")
// after
exec.Command("kubectl", "get", "services", "--watch") // ensure kubectl is on PATH
Defensive patterns

Strategy: try-catch

Validate before calling

if _, err := exec.LookPath("kubectl"); err != nil {
    return fmt.Errorf("kubectl not found in PATH")
}
if _, err := os.Stat(kubeconfig); err != nil {
    return fmt.Errorf("kubeconfig missing: %w", err)
}

Try / catch

if err := startAndStreamKubectl(cmd); err != nil {
    if errors.Is(err, exec.ErrNotFound) || strings.Contains(err.Error(), "not found") {
        log.Println("install kubectl in the guest")
    } else if errors.Is(err, context.Canceled) {
        // expected during shutdown; ignore
    }
}

Prevention

When it happens

Trigger: The streaming kubectl command cannot be started: the kubectl binary is missing or not executable (exec: not found / permission denied), or the process exits during Wait with a nonzero status (context canceled, auth failure, connection loss) - the Wait variant wraps the same message.

Common situations: kubectl absent from PATH in the guest; kubeconfig removed or made invalid while streaming; cluster API server restarting mid-stream; guestagent context canceled during shutdown (benign during teardown).

Related errors


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