derailed/k9s · error
user is not authorized to list pod metrics
Error message
user is not authorized to list pod metrics
What it means
Raised at internal/client/metrics.go:100 inside checkAccess when the RBAC check for a single pod's metrics returns auth=false. The message string is the const in FetchPodMetrics (metrics.go:293), checked at :299; the call chain is typically FetchContainersMetrics -> FetchPodMetrics. Same GVR as [6] (pods.metrics.k8s.io) but the message marks the single-pod/containers path.
Source
Thrown at internal/client/metrics.go:100
tcpu += mx.AllocatableCPU
tmem += mx.AllocatableMEM
}
mx.PercCPU, mx.PercMEM = ToPercentage(ccpu, tcpu), ToPercentage(cmem, tmem)
return nil
}
func (m *MetricsServer) checkAccess(ns string, gvr *GVR, msg string) error {
if !m.HasMetrics() {
return errors.New("no metrics-server detected on cluster")
}
auth, err := m.CanI(ns, gvr, "", ListAccess)
if err != nil {
return err
}
if !auth {
return errors.New(msg)
}
return nil
}
// NodesMetrics retrieves metrics for a given set of nodes.
func (*MetricsServer) NodesMetrics(nodes *v1.NodeList, metrics *mv1beta1.NodeMetricsList, mmx NodesMetrics) {
if nodes == nil || metrics == nil {
return
}
for i := range nodes.Items {
mmx[nodes.Items[i].Name] = NodeMetrics{
AllocatableCPU: nodes.Items[i].Status.Allocatable.Cpu().MilliValue(),
AllocatableMEM: ToMB(nodes.Items[i].Status.Allocatable.Memory().Value()),
AllocatableEphemeral: ToMB(nodes.Items[i].Status.Allocatable.StorageEphemeral().Value()),
TotalCPU: nodes.Items[i].Status.Capacity.Cpu().MilliValue(),
TotalMEM: ToMB(nodes.Items[i].Status.Capacity.Memory().Value()),
TotalEphemeral: ToMB(nodes.Items[i].Status.Capacity.StorageEphemeral().Value()),View on GitHub (pinned to 2d3ccc6ba2)
Solutions
- Grant get/list on pods.metrics.k8s.io in the pod's namespace (Role + RoleBinding), verify with kubectl auth can-i list pods.metrics.k8s.io -n <ns>
- If per-pod detail is all that is needed, a namespaced Role is sufficient — no ClusterRole required
- Skip the containers-metrics UI when the check fails rather than surfacing the raw error
Example fix
// before
cmx, err := metricsSrv.FetchContainersMetrics(ctx, fqn)
// after
ns, _ := client.Namespaced(fqn)
auth, err := metricsSrv.CanI(ns, client.PmxGVR, "", client.ListAccess)
if err == nil && !auth {
return nil, nil // user cannot view pod metrics; hide column data
}
cmx, err := metricsSrv.FetchContainersMetrics(ctx, fqn) Defensive patterns
Strategy: validation
Validate before calling
ns, _ := client.Namespaced(fqn)
auth, err := metricsSrv.CanI(ns, client.PmxGVR, "", client.ListAccess)
if err == nil && !auth {
return nil, nil // hide container metrics
}
cmx, err := metricsSrv.FetchContainersMetrics(ctx, fqn) Try / catch
if _, err := metricsSrv.FetchContainersMetrics(ctx, fqn); err != nil {
if strings.Contains(err.Error(), "not authorized to list pod metrics") {
// render pod view without per-container usage columns
}
} Prevention
- Gate container-metrics views on the same CanI check the fetcher uses
- Grant the metrics role in namespaces where users open pod details
- Do not retry authorization errors — they are deterministic until RBAC changes
When it happens
Trigger: Calling FetchContainersMetrics(ctx, fqn) or FetchPodMetrics(ctx, fqn) for a pod whose namespace grants no list on pods.metrics.k8s.io — CanI(ns, PmxGVR, "", [list]) returns false.
Common situations: Opening a pod's containers-metrics view (shift+ins in k9s) as a user whose role covers core pods but not metrics.k8s.io; ns derived from the pod FQN being BlankNamespace during all-namespaces browsing.
Related errors
- user is not authorized to list node metrics
- user is not authorized to list pods metrics
- no metrics-server detected on cluster
- (%s) access denied for user on resource %q:%s in namespace %
- user is not authorized to run jobs
AI-assisted analysis of derailed/k9s@2d3ccc6ba2 (2026-08-15).
Data as JSON: /api/errors/eda489393493847a.
Report an issue: GitHub.