derailed/k9s · error

user is not authorized to list pods

Error message

user is not authorized to list pods

What it means

FetchPods (used by the recorder/alarm fan-out) authorizes list on pods in namespace ns via CanI and errors when denied. The requirement is the list verb on core pods in that specific namespace — nothing namespace-scoped shorter than that will pass.

Source

Thrown at internal/dao/recorder.go:282

		r.series.Add(pt.Time, pt, seriesCacheExpiry)
		r.mx.Lock()
		defer r.mx.Unlock()
		if r.mxChan != nil {
			r.mxChan <- TimeSeries{pt}
		}
	}

	return nil
}

// FetchPods retrieves all pods in a given namespace.
func FetchPods(_ context.Context, f Factory, ns string) (*v1.PodList, error) {
	auth, err := f.Client().CanI(ns, client.PodGVR, "pods", []string{client.ListVerb})
	if err != nil {
		return nil, err
	}
	if !auth {
		return nil, fmt.Errorf("user is not authorized to list pods")
	}

	oo, err := f.List(client.PodGVR, ns, false, labels.Everything())
	if err != nil {
		return nil, err
	}
	pp := make([]v1.Pod, 0, len(oo))
	for _, o := range oo {
		var pod v1.Pod
		err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &pod)
		if err != nil {
			return nil, err
		}
		pp = append(pp, pod)
	}

	return &v1.PodList{Items: pp}, nil
}

View on GitHub (pinned to 2d3ccc6ba2)

Solutions

  1. Grant list on pods in the namespace: resources ["pods"] verbs ["list","get"] via Role+RoleBinding
  2. Verify: kubectl auth can-i list pods -n <ns>
  3. Restrict the feature to namespaces the identity can read instead of granting cluster-wide access
Defensive patterns

Strategy: validation

Validate before calling

ok, err := f.Client().CanI(ns, client.PodGVR, "", []string{"list"})
if err != nil { return err }
if !ok { return fmt.Errorf("cannot list pods in %s; skipping", ns) }

Try / catch

if _, err := dao.FetchPods(ctx, f, ns); err != nil {
    if strings.Contains(err.Error(), "not authorized to list pods") {
        // skip this namespace in fan-out loops instead of aborting the run
    }
}

Prevention

When it happens

Trigger: CanI(ns, pods, list) false — the active identity has no Role/RoleBinding granting pod list in the namespace being scanned.

Common situations: Recorder or cross-namespace features walking into namespaces the user cannot read; service accounts scoped to one namespace used against another; kubeconfig contexts switched after the session started.

Related errors


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