lima-vm/lima · error

failed to run %v: expected `yes`, got %#q

Error message

failed to run %v: expected `yes`, got %#q

What it means

After canGetServices' kubectl probe exits successfully, its stdout must equal `yes` (after trimming whitespace); anything else throws this error. This is the library's way of validating that the probe actually reported service accessibility, not just that kubectl exited cleanly.

Source

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

			return kc
		}
	}
	return ""
}

func canGetServices(ctx context.Context, kubectl, kubeconfig string) error {
	cmd := exec.CommandContext(ctx, kubectl, "auth", "can-i", "get", "service")
	if kubeconfig != "" {
		cmd.Env = append(os.Environ(), "KUBECONFIG="+kubeconfig)
	}
	var stdout, stderr bytes.Buffer
	cmd.Stdout = &stdout
	cmd.Stderr = &stderr
	if err := cmd.Run(); err != nil {
		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)

View on GitHub (pinned to dd909d0973)

Solutions

  1. Inspect the got=... value in the message to see what kubectl actually printed.
  2. Run the same kubectl command manually in the guest and compare output.
  3. Align kubectl client version with the cluster server version.
  4. Silence kubectl warnings (e.g. --warnings-as-errors=false handling or redirect warnings to stderr) so stdout contains only the expected `yes`.

Example fix

// before (output includes warnings)
expected `yes`, got "Warning: v1 Endpoints...\nno"
// after
kubectl ... 2>/dev/null | tail -n1  # ensure only the verdict reaches stdout
Defensive patterns

Strategy: try-catch

Validate before calling

out, err := exec.Command("kubectl", "--kubeconfig", kubeconfig, "auth", "can-i", "get", "services").Output()
if err == nil && strings.TrimSpace(string(out)) != "yes" {
    return fmt.Errorf("RBAC denies service listing; kubectl will answer %q", strings.TrimSpace(string(out)))
}

Try / catch

if err := canGetServices(ctx, kubeconfig); err != nil {
    if strings.Contains(err.Error(), "expected `yes`") {
        // inspect got=... in the message; usually RBAC denial or polluted stdout
    }
}

Prevention

When it happens

Trigger: The kubectl probe command exits 0 but prints something other than `yes`: kubectl prints warnings or help text, the wrong subcommand is invoked, a plugin intercepts output, or the cluster answers but the probe logic returns no/false unexpectedly.

Common situations: Kubectl version mismatch altering output format; server reachable but authorization denied while kubectl still exits 0 with an API error message; kubectl output polluted by warnings (e.g. deprecation notices) on stdout.

Related errors


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