## TL;DR
kubectl top depends entirely on metrics-server, and when it shows nothing the problem is almost always metrics-server itself: not installed, crashing, or unable to reach kubelets. Work through it in order: is metrics-server running, can it scrape kubelets (TLS is the usual suspect), and is the metrics API actually serving. Nine times out of ten it is one of those three.

## The query
```text
kubectl top shows no metrics: metrics-server troubleshooting
```

## Use this when
- kubectl top returns errors or empty tables
- HPA is not scaling and you suspect metrics
- A new or upgraded cluster has no resource metrics
- Dashboards that read the metrics API are blank

## Not for when
- Setting up Prometheus or full monitoring stacks
- Application-level custom metrics
- Node resource pressure itself (use the metrics once they work)

## Steps

### Step 1: Check if metrics-server is running
Look for the metrics-server deployment in kube-system and check its pod status and logs. On managed clusters it should exist by default; on kubeadm or k3s clusters it may be missing or disabled.
Expected output: a running metrics-server pod, or a clear "not installed" answer that sends you to install it.

### Step 2: Read the metrics-server logs for scrape errors
The logs name the failure directly: connection refused to kubelets, TLS verification failures, or timeouts. TLS issues with kubelet certificates are the most common cause on clusters with custom CA setups.
Expected output: a specific error naming which kubelet or what TLS problem is blocking scrapes.

### Step 3: Verify kubelet connectivity from the metrics-server pod
The server needs to reach each kubelet's HTTPS endpoint. Network policies, firewalls, or wrong address types (hostname vs internal IP) break this. Check that the addresses metrics-server uses match addresses that actually route.
Expected output: metrics-server can open HTTPS connections to kubelets on all nodes.

### Step 4: Check the metrics API registration
Query the API aggregation layer to confirm the metrics.k8s.io API service is available and not reporting failures. A broken apiservice registration makes kubectl top fail even with a healthy metrics-server.
Expected output: the metrics.k8s.io APIService shows Available=True.

### Step 5: Confirm with kubectl top after a short wait
Metrics-server scrapes on an interval (default 60 seconds), so fresh installs need a minute or two before data appears. Run kubectl top nodes and kubectl top pods; both should return values.
Expected output: CPU and memory columns populated for nodes and pods.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_8CbOK1bfQxjI64s6tBy0Lg
