{"record":{"id":"d3b3afe60cc9112c","repo":"derailed/k9s","slug":"user-is-not-authorized-to-list-node-metrics","errorCode":null,"errorMessage":"user is not authorized to list node metrics","messagePattern":"user is not authorized to list node metrics","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/client/metrics.go","lineNumber":100,"sourceCode":"\t\ttcpu += mx.AllocatableCPU\n\t\ttmem += mx.AllocatableMEM\n\t}\n\tmx.PercCPU, mx.PercMEM = ToPercentage(ccpu, tcpu), ToPercentage(cmem, tmem)\n\n\treturn nil\n}\n\nfunc (m *MetricsServer) checkAccess(ns string, gvr *GVR, msg string) error {\n\tif !m.HasMetrics() {\n\t\treturn errors.New(\"no metrics-server detected on cluster\")\n\t}\n\n\tauth, err := m.CanI(ns, gvr, \"\", ListAccess)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif !auth {\n\t\treturn errors.New(msg)\n\t}\n\treturn nil\n}\n\n// NodesMetrics retrieves metrics for a given set of nodes.\nfunc (*MetricsServer) NodesMetrics(nodes *v1.NodeList, metrics *mv1beta1.NodeMetricsList, mmx NodesMetrics) {\n\tif nodes == nil || metrics == nil {\n\t\treturn\n\t}\n\n\tfor i := range nodes.Items {\n\t\tmmx[nodes.Items[i].Name] = NodeMetrics{\n\t\t\tAllocatableCPU:       nodes.Items[i].Status.Allocatable.Cpu().MilliValue(),\n\t\t\tAllocatableMEM:       ToMB(nodes.Items[i].Status.Allocatable.Memory().Value()),\n\t\t\tAllocatableEphemeral: ToMB(nodes.Items[i].Status.Allocatable.StorageEphemeral().Value()),\n\t\t\tTotalCPU:             nodes.Items[i].Status.Capacity.Cpu().MilliValue(),\n\t\t\tTotalMEM:             ToMB(nodes.Items[i].Status.Capacity.Memory().Value()),\n\t\t\tTotalEphemeral:       ToMB(nodes.Items[i].Status.Capacity.StorageEphemeral().Value()),","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/derailed/k9s/blob/2d3ccc6ba2ce98c3781bfc441bb3e884f072774f/internal/client/metrics.go#L82-L118","documentation":"Raised at internal/client/metrics.go:100 inside checkAccess when the RBAC check for the node-metrics GVR (nodes.metrics.k8s.io, checked at ClusterScope) returns auth=false. The message is the caller-supplied const in FetchNodesMetrics (metrics.go:152) and FetchNodeMetrics (:194). It means the user is connected and metrics-server exists, but lacks the list verb on nodes.metrics.k8s.io.","triggerScenarios":"Any call to FetchNodesMetrics or FetchNodeMetrics where CanI(ClusterScope, NmxGVR, \"\", [list]) returns false — i.e. no ClusterRole/Binding granting get/list on nodes.metrics.k8s.io.","commonSituations":"Restricted-view users provisioned only for core resources; operators on shared clusters where metrics are exposed only to SRE roles; fresh service-account used with k9s pulse view; cluster-role aggregation excluding metrics group.","solutions":["Grant list/get on nodes.metrics.k8s.io via a ClusterRole + ClusterRoleBinding (e.g. the standard metrics-server scrapers view or kubectl create role/clusterrole with resource nodes.metrics.k8s.io)","Verify with kubectl auth can-i list nodes.metrics.k8s.io","If access is intentionally restricted, suppress the pulse/metrics views for this user instead of erroring"],"exampleFix":"// before\nmx, err := metricsSrv.FetchNodesMetrics(ctx)\n\n// after (defense: check first, degrade quietly)\nauth, err := metricsSrv.CanI(client.ClusterScope, client.NmxGVR, \"\", client.ListAccess)\nif err == nil && !auth {\n    return nil, nil // no metrics permission; skip node metrics\n}\nmx, err := metricsSrv.FetchNodesMetrics(ctx)","handlingStrategy":"validation","validationCode":"auth, err := metricsSrv.CanI(client.ClusterScope, client.NmxGVR, \"\", client.ListAccess)\nif err == nil && !auth {\n    return nil, nil // degrade: hide node metrics\n}\nmx, err := metricsSrv.FetchNodesMetrics(ctx)","typeGuard":null,"tryCatchPattern":"if _, err := metricsSrv.FetchNodesMetrics(ctx); err != nil {\n    if strings.Contains(err.Error(), \"not authorized to list node metrics\") {\n        // hide pulse view / notify user about missing ClusterRole\n    }\n}","preventionTips":["Pre-check CanI for nodes.metrics.k8s.io and remember per-user grants","Include metrics.k8s.io resources in baseline cluster roles for operator groups","Verify with kubectl auth can-i list nodes.metrics.k8s.io before filing bugs"],"tags":["kubernetes","rbac","metrics-server","authorization"],"backgroundTag":null,"analyzedSha":"2d3ccc6ba2ce98c3781bfc441bb3e884f072774f","analyzedAt":"2026-08-15T16:09:14.432Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}