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 errView on GitHub (pinned to 2d3ccc6ba2)
Solutions
- Inspect the per-context file under $K9S_CONFIG_DIR/contexts/<cluster>/<ctx>.yaml — ensure it has a top-level 'context:' section
- Delete the suspect file so k9s regenerates a complete default on next activation
- Recreate with valid minimal content: context:\n namespace:\n active: default
- 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
- Never leave per-context yaml files empty — either delete them or keep a valid 'context:' section
- If this fires with well-formed configs, preserve the files and report a k9s bug (defensive check breached)
- Track k9s config dir in git to detect exactly when a file became degenerate
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
- re.Description()
- no active context available
- no benchmark dir found in context
- no path specified in context
- expecting context GVR
AI-assisted analysis of derailed/k9s@2d3ccc6ba2 (2026-08-15).
Data as JSON: /api/errors/5e73ce98065f55f4.
Report an issue: GitHub.