{"record":{"id":"2088466e0a3f3acd","repo":"derailed/k9s","slug":"access-denied-for-user-on-s-s","errorCode":null,"errorMessage":"access denied for user on: %s/%s","messagePattern":"access denied for user on: (.+?)/(.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/view/browser.go","lineNumber":593,"sourceCode":"\tif err := runK(app, &shellOpts{clear: true, args: args}); err != nil {\n\t\tapp.Flash().Errf(\"Edit command failed: %s\", err)\n\t}\n\n\treturn nil\n}\n\nfunc (b *Browser) switchNamespaceCmd(evt *tcell.EventKey) *tcell.EventKey {\n\ti, err := strconv.Atoi(string(evt.Rune()))\n\tif err != nil {\n\t\tslog.Error(\"Unable to convert keystroke\", slogs.Error, err)\n\t\treturn nil\n\t}\n\tns := b.namespaces[i]\n\n\tauth, err := b.App().factory.Client().CanI(ns, b.GVR(), \"\", client.ListAccess)\n\tif !auth {\n\t\tif err == nil {\n\t\t\terr = fmt.Errorf(\"access denied for user on: %s/%s\", ns, b.GVR())\n\t\t}\n\t\tb.App().Flash().Err(err)\n\t\treturn nil\n\t}\n\n\tif err := b.app.switchNS(ns); err != nil {\n\t\tb.App().Flash().Err(err)\n\t\treturn nil\n\t}\n\tb.setNamespace(ns)\n\tif client.IsClusterScoped(ns) {\n\t\tb.app.Flash().Infof(\"Viewing %s...\", b.GVR())\n\t} else {\n\t\tb.app.Flash().Infof(\"Viewing %s in namespace `%s`...\", b.GVR(), client.PrintNamespace(ns))\n\t}\n\tb.refresh()\n\tb.UpdateTitle()\n\tb.SelectRow(1, 0, true)","sourceCodeStart":575,"sourceCodeEnd":611,"githubUrl":"https://github.com/derailed/k9s/blob/2d3ccc6ba2ce98c3781bfc441bb3e884f072774f/internal/view/browser.go#L575-L611","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Run kubectl auth can-i list <resource> -n <namespace> to confirm the denial.","Request list permission for the GVR in that namespace (Role with verbs [\"list\"], or list at cluster scope for cluster-scoped GVRs).","Switch to a GVR you can list everywhere (e.g. namespaces) before quick-switching, or use the namespace picker over a permitted resource.","Remove stale namespace favorites bound to namespaces you no longer access."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"auth, err := b.App().factory.Client().CanI(ns, b.GVR(), \"\", client.ListAccess)\nif err != nil {\n    b.App().Flash().Err(err)\n    return nil\n}\nif !auth {\n    b.App().Flash().Errf(\"no list access on %s in %s\", b.GVR(), ns)\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Bind namespace quick-switch keys only to namespaces the token can list for common GVRs.","Check CanI on the active GVR before registering number-key bindings.","On role changes, restart the session so favorites and RBAC stay in sync."],"tags":["kubernetes","rbac","navigation","namespace"],"backgroundTag":null,"analyzedSha":"2d3ccc6ba2ce98c3781bfc441bb3e884f072774f","analyzedAt":"2026-08-15T16:09:14.432Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}