derailed/k9s · error

context %q does not exist

Error message

context %q does not exist

What it means

Returned by Config.SwitchContext (internal/client/config.go:94) when the helper GetContext(name) cannot find the requested context in the merged kubeconfig. SwitchContext deliberately wraps the miss with the requested name because GetContext's own message ('getcontext - invalid context specified') lacks the operation context. The switch is aborted before any kubeconfig mutation happens.

Source

Thrown at internal/client/config.go:94

func (c *Config) Flags() *genericclioptions.ConfigFlags {
	return c.flags
}

func (c *Config) RawConfig() (api.Config, error) {
	return c.clientConfig().RawConfig()
}

func (c *Config) clientConfig() clientcmd.ClientConfig {
	return c.flags.ToRawKubeConfigLoader()
}

func (*Config) reset() {}

// SwitchContext changes the kubeconfig context to a new cluster.
func (c *Config) SwitchContext(name string) error {
	ct, err := c.GetContext(name)
	if err != nil {
		return fmt.Errorf("context %q does not exist", name)
	}
	// !!BOZO!! Do you need to reset the flags?
	flags := genericclioptions.NewConfigFlags(UsePersistentConfig)
	flags.Context, flags.ClusterName = &name, &ct.Cluster
	flags.Namespace = c.flags.Namespace
	flags.Timeout = c.flags.Timeout
	flags.KubeConfig = c.flags.KubeConfig
	flags.Impersonate = c.flags.Impersonate
	flags.ImpersonateGroup = c.flags.ImpersonateGroup
	flags.ImpersonateUID = c.flags.ImpersonateUID
	flags.Insecure = c.flags.Insecure
	flags.BearerToken = c.flags.BearerToken

	c.flags = flags

	return nil
}

View on GitHub (pinned to 2d3ccc6ba2)

Solutions

  1. List valid names with kubectl config get-contexts and retry with the exact spelling (names are case-sensitive)
  2. Verify which files are merged: echo $KUBECONFIG — the context may exist in a file outside the merge order
  3. Create the context if it should exist: kubectl config set-context prod --cluster=... --user=...
  4. Restart k9s after kubeconfig changes so the in-memory view is refreshed

Example fix

# before
kubectl config use-context prodd   # typo, fails later in k9s too

# after
kubectl config get-contexts         # confirm exact name 'prod'
kubectl config use-context prod
Defensive patterns

Strategy: validation

Validate before calling

func safeSwitchContext(cfg *client.Config, name string) error {
	ctxs, err := cfg.Contexts()
	if err != nil {
		return fmt.Errorf("kubeconfig unreadable: %w", err)
	}
	if _, ok := ctxs[name]; !ok {
		return fmt.Errorf("context %q not in kubeconfig (have: %v)",
			name, maps.Keys(ctxs))
	}
	return cfg.SwitchContext(name)
}

Try / catch

if err := cfg.SwitchContext(name); err != nil {
	if strings.Contains(err.Error(), "does not exist") {
		// prompt the user to pick from `kubectl config get-contexts`
	}
	return err
}

Prevention

When it happens

Trigger: Calling SwitchContext("prod") when 'prod' is not a key in the contexts map of the merged KUBECONFIG files — typo in the name, the kubeconfig file was replaced/deleted after load, or the context lives in a kubeconfig file not listed in the KUBECONFIG search path.

Common situations: Renaming or deleting a context with kubectl config delete-context while k9s is running; a typo in the :ctx command; KUBECONFIG env var differing between the shell that launched k9s and the one used to create the context.

Related errors


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