derailed/k9s · error

context activation failed for: %s

Error message

context activation failed for: %s

What it means

Returned at the tail of K9s.ActivateContext (internal/config/k9s.go:298): after the context config is loaded and namespace defaults applied, the active config's Context pointer is still nil. This is a defensive invariant check that is nearly unreachable — if Context were nil with a non-blank context namespace, the dereference a few lines earlier would have panicked first; it can only fire when the kubeconfig context has no namespace AND no active namespace was set, leaving cfg.Context nil (e.g. an effectively empty per-context yaml).

Source

Thrown at internal/config/k9s.go:298

				slog.Debug("Setting proxy address", slogs.Address, cfg.Context.Proxy.Address)
				return url.Parse(cfg.Context.Proxy.Address)
			})

			if !k.conn.CheckConnectivity() {
				return nil, fmt.Errorf("unable to connect to context %q", contextName)
			}
		}
	}

	k.Validate(k.conn, contextName, ct.Cluster)
	// If the context specifies a namespace, use it!
	if ns := ct.Namespace; ns != client.BlankNamespace {
		k.getActiveConfig().Context.Namespace.Active = ns
	} else if k.getActiveConfig().Context.Namespace.Active == "" {
		k.getActiveConfig().Context.Namespace.Active = client.DefaultNamespace
	}
	if k.getActiveConfig().Context == nil {
		return nil, fmt.Errorf("context activation failed for: %s", contextName)
	}

	return k.getActiveConfig().Context, nil
}

// Reload reloads the context config from disk.
func (k *K9s) Reload() error {
	// Switching context skipping reload...
	if k.getContextSwitch() {
		return nil
	}
	ctxName := k.getActiveContextName()
	if ctxName == "" {
		return errors.New("no active context available")
	}
	ct, err := k.ks.GetContext(ctxName)
	if err != nil {
		return err

View on GitHub (pinned to 2d3ccc6ba2)

Solutions

  1. Inspect the per-context file under $K9S_CONFIG_DIR/contexts/<cluster>/<ctx>.yaml — ensure it has a top-level 'context:' section
  2. Delete the suspect file so k9s regenerates a complete default on next activation
  3. Recreate with valid minimal content: context:\n namespace:\n active: default
  4. If it reproduces with a well-formed file, capture the config and report it as a k9s bug (invariant breach)

Example fix

# before: contexts/prod-c/prod.yaml is empty or lacks 'context:'
{} 

# after
context:
  namespace:
    active: default
    favorites:
      default: []
Defensive patterns

Strategy: try-catch

Try / catch

if _, err := k9s.ActivateContext(name); err != nil {
	if strings.Contains(err.Error(), "context activation failed for") {
		// invariant breach: per-context config has no 'context:' section.
		// Delete the context yaml so defaults regenerate, then retry once.
		_ = os.Remove(filepath.Join(k9sConfigDir, "clusters", cluster, name+".yaml"))
		_, err = k9s.ActivateContext(name)
	}
}

Prevention

When it happens

Trigger: A per-context config file that unmarshals to a data.Config with a nil Context (empty or context-less yaml) combined with a kubeconfig context that sets no namespace and no previously active namespace. Realistically rare; mostly a canary for config-dir corruption or an unexpected dir.Load result.

Common situations: Empty per-context yaml created by a crashed first run; manual deletion of file contents while keeping the file; edge-case downgrades where the loader shape changed.

Related errors


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