derailed/k9s · warning

access denied for user on: %s/%s

Error message

access denied for user on: %s/%s

What it means

Namespace quick-switch (typing a namespace's index digit) checks CanI(ns, gvr, "", ListAccess) for the current GVR; it returned false. The user can see the namespace in the favorites/switch list but cannot list the currently viewed resource type there, so the switch is blocked. If err is non-nil the flash shows the raw error instead.

Source

Thrown at internal/view/browser.go:593

	if err := runK(app, &shellOpts{clear: true, args: args}); err != nil {
		app.Flash().Errf("Edit command failed: %s", err)
	}

	return nil
}

func (b *Browser) switchNamespaceCmd(evt *tcell.EventKey) *tcell.EventKey {
	i, err := strconv.Atoi(string(evt.Rune()))
	if err != nil {
		slog.Error("Unable to convert keystroke", slogs.Error, err)
		return nil
	}
	ns := b.namespaces[i]

	auth, err := b.App().factory.Client().CanI(ns, b.GVR(), "", client.ListAccess)
	if !auth {
		if err == nil {
			err = fmt.Errorf("access denied for user on: %s/%s", ns, b.GVR())
		}
		b.App().Flash().Err(err)
		return nil
	}

	if err := b.app.switchNS(ns); err != nil {
		b.App().Flash().Err(err)
		return nil
	}
	b.setNamespace(ns)
	if client.IsClusterScoped(ns) {
		b.app.Flash().Infof("Viewing %s...", b.GVR())
	} else {
		b.app.Flash().Infof("Viewing %s in namespace `%s`...", b.GVR(), client.PrintNamespace(ns))
	}
	b.refresh()
	b.UpdateTitle()
	b.SelectRow(1, 0, true)

View on GitHub (pinned to 2d3ccc6ba2)

Solutions

  1. Run kubectl auth can-i list <resource> -n <namespace> to confirm the denial.
  2. Request list permission for the GVR in that namespace (Role with verbs ["list"], or list at cluster scope for cluster-scoped GVRs).
  3. Switch to a GVR you can list everywhere (e.g. namespaces) before quick-switching, or use the namespace picker over a permitted resource.
  4. Remove stale namespace favorites bound to namespaces you no longer access.
Defensive patterns

Strategy: validation

Validate before calling

auth, err := b.App().factory.Client().CanI(ns, b.GVR(), "", client.ListAccess)
if err != nil {
    b.App().Flash().Err(err)
    return nil
}
if !auth {
    b.App().Flash().Errf("no list access on %s in %s", b.GVR(), ns)
    return nil
}

Prevention

When it happens

Trigger: Pressing a number key bound to b.namespaces[i] while the active browser's GVR is not listable in that namespace (Role grants list only in other namespaces; namespace-stage RBAC; cluster-scoped resource with namespace-filtered roles).

Common situations: Per-namespace RBAC segregation (team A's namespaces vs team B's); switching while on a cluster-scoped custom resource; stale favorites referencing namespaces the token lost after a role change.

Understand the failure class

Related errors


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