derailed/k9s · error

kubectl command must not be in the current working directory

Error message

kubectl command must not be in the current working directory: %w

What it means

runK() resolves kubectl with exec.LookPath. Since Go 1.19, LookPath returns the sentinel error exec.ErrDot when the resolved binary is a relative path — i.e. kubectl was found in the current working directory (./kubectl), which Go refuses to use implicitly for security (a hostile writable directory could hijack command resolution). k9s surfaces this explicitly instead of silently running the local binary.

Source

Thrown at internal/view/exec.go:61

var editorEnvVars = []string{"K9S_EDITOR", "KUBE_EDITOR", "EDITOR"}

type shellOpts struct {
	clear, background bool
	pipes             []string
	binary            string
	banner            string
	args              []string
}

func (s shellOpts) String() string {
	return fmt.Sprintf("%s %s", s.binary, strings.Join(s.args, " "))
}

func runK(a *App, opts *shellOpts) error {
	bin, err := exec.LookPath("kubectl")
	if errors.Is(err, exec.ErrDot) {
		return fmt.Errorf("kubectl command must not be in the current working directory: %w", err)
	}
	if err != nil {
		return fmt.Errorf("kubectl command is not in your path: %w", err)
	}
	args := []string{opts.args[0]}
	if u, err := a.Conn().Config().ImpersonateUser(); err == nil {
		args = append(args, "--as", u)
	}
	if g, err := a.Conn().Config().ImpersonateGroups(); err == nil {
		args = append(args, "--as-group", g)
	}
	if isInsecure := a.Conn().Config().Flags().Insecure; isInsecure != nil && *isInsecure {
		args = append(args, "--insecure-skip-tls-verify")
	}
	args = append(args, "--context", a.Config.K9s.ActiveContextName())
	if cfg := a.Conn().Config().Flags().KubeConfig; cfg != nil && *cfg != "" {
		args = append(args, "--kubeconfig", *cfg)
	}

View on GitHub (pinned to 2d3ccc6ba2)

Solutions

  1. Install kubectl into a real PATH directory (e.g. /usr/local/bin/kubectl) so it resolves absolutely
  2. Remove or rename the ./kubectl in your working directory before launching k9s
  3. Launch k9s from a directory that does not contain a kubectl binary

Example fix

# before — running k9s from a dir containing ./kubectl
$ cd ~/project && ls kubectl
$ k9s            # any kubectl-backed feature fails with ErrDot
# after
$ sudo mv ~/project/kubectl /usr/local/bin/kubectl
$ k9s            # resolves via PATH, works
Defensive patterns

Strategy: validation

Validate before calling

// preflight: resolve kubectl and refuse cwd-relative hits before running
bin, err := exec.LookPath("kubectl")
if errors.Is(err, exec.ErrDot) {
    return fmt.Errorf("refusing ./kubectl — install kubectl on PATH")
}
if path.IsAbs(bin) { /* safe to proceed */ }

Prevention

When it happens

Trigger: Starting k9s in a directory that contains a kubectl executable and no earlier PATH entry wins — e.g. you downloaded kubectl into a project folder and launch k9s from there, invoking any kubectl-shelling feature (shell, port-forward helpers, kubectl prompts).

Common situations: Per-project kubectl binaries (version managers that drop kubectl into ./bin with PATH=.:/bin styles); CI scripts that cd into a tools directory; users following install docs that say 'download kubectl here' and run k9s in the same dir.

Related errors


AI-assisted analysis of derailed/k9s@2d3ccc6ba2 (2026-08-15). Data as JSON: /api/errors/4af179fbd7d2ca9d. Report an issue: GitHub.