> ## Documentation Index
> Fetch the complete documentation index at: https://radarhq.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kubernetes upgrade impact

> Find version skew, removed APIs, drain blockers, webhook failures, deprecated configuration, and incomplete evidence before upgrading a Kubernetes cluster.

<Badge color="green" size="sm" stroke>Available in Radar v1.9.0+</Badge>

Upgrade impact answers a focused question: **what in this cluster will block or need attention before the next Kubernetes minor upgrade?**

Open **Checks → Upgrade impact**. In Radar Cloud, choose the connected cluster to analyze; standalone Radar opens the current cluster directly. Radar detects the current control-plane version, selects the next minor by default, and evaluates live cluster state plus the source configuration it can recover. The scan is read-only and does not start or schedule an upgrade.

<Note>
  Upgrade impact reports what Radar can prove from the available evidence. "No blockers found" is not a readiness guarantee when a source is unavailable, the scan is namespace-scoped, or the target is newer than Radar's reviewed catalog.
</Note>

<img src="https://mintcdn.com/skyhook/j1Ebxln7HOwo86x4/images/upgrade-impact-overview.png?fit=max&auto=format&n=j1Ebxln7HOwo86x4&q=85&s=6b258cf9fcd7eb0c88755fe117f3d1af" alt="Upgrade impact overview showing the Kubernetes target, scheduling verdict, coverage notices, and checks ordered by required action" width="1920" height="1080" data-path="images/upgrade-impact-overview.png" />

## Run a scan

1. Connect Radar to the cluster you plan to upgrade.
2. Open **Checks** in the navigation rail, then select **Upgrade impact**. In Radar Cloud, choose the connected cluster when prompted.
3. Confirm the target Kubernetes version in the page header.
4. Start with **Blocked**, then **Warning**, then **Review** rows. Expand a row to see the exact resource, evidence path, impact, remediation, and upstream references.
5. Resolve each finding or consciously decide to proceed, refresh the page, and run the check again before scheduling the upgrade.

Radar orders checks by required action. Repeated findings with the same impact and remediation share one explanation, followed by a compact list of affected resources.

The table header distinguishes checks evaluated for the selected path, checks that apply, checks with partial evidence, and checks found not applicable. Expand **Coverage and methodology** to see the reviewed catalog boundary and why checks for unrelated Kubernetes releases are excluded instead of counted as artificial passes.

<img src="https://mintcdn.com/skyhook/j1Ebxln7HOwo86x4/images/upgrade-impact-finding-detail.png?fit=max&auto=format&n=j1Ebxln7HOwo86x4&q=85&s=736a37218d881b0c6a069cc85e3cdf0d" alt="Expanded node drain check showing the issue type, impact, remediation, and affected Pods" width="1920" height="1080" data-path="images/upgrade-impact-finding-detail.png" />

## How to read the result

| Result             | Meaning                                                                                                                  |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------ |
| **Blocked**        | Radar found a condition that is incompatible with the target version. Fix it before upgrading.                           |
| **Warning**        | Radar found concrete evidence of likely operational impact. Resolve it or explicitly accept the risk before upgrading.   |
| **Review**         | Radar found a static exposure or intent-dependent configuration. Verify that it is deliberate and safe for this upgrade. |
| **Passed**         | The applicable check passed for the evidence Radar inspected. Expand the row to see its evidence scope.                  |
| **Incomplete**     | Radar could not verify the check because required evidence was unavailable, unreadable, or outside the scan scope.       |
| **Not applicable** | The check does not apply to this cluster, provider, or installed API set.                                                |

When a check has both an actionable finding and an evidence gap, the row keeps the highest action level and also contributes to the partial-evidence count. Expanding the row shows the coverage caveat; an amber or blue result never hides unread evidence.

The top banner rolls those rows into one scheduling verdict:

* **Blocked** when at least one blocker exists.
* **No blockers found · warnings need attention** when there are warnings but no blockers.
* **No blockers found · items need review** when there are review items but no blockers or warnings.
* **No blockers found · coverage is incomplete** when Radar lacks evidence or the target is beyond the reviewed catalog.
* **No blockers found for Kubernetes X.Y** only when every applicable reviewed check passes and coverage is complete.

## Checks included

Radar evaluates 18 checks. Target-independent checks run for every scan. Release-specific checks activate whenever the selected upgrade path reaches their `appliesFrom` version, including intermediate minors.

| Check                                                                             | Applies                   | Primary evidence                                     |
| --------------------------------------------------------------------------------- | ------------------------- | ---------------------------------------------------- |
| [Control plane version sequence](#control-plane-version-sequence)                 | Every target              | Current and target versions                          |
| [Removed API usage](#removed-api-usage)                                           | Every target              | API server request metrics                           |
| [Source manifest API versions](#source-manifest-api-versions)                     | Every target              | Helm and kubectl source manifests                    |
| [Node readiness](#node-readiness)                                                 | Every target              | Node `Ready` conditions                              |
| [Kubelet version skew](#kubelet-version-skew)                                     | Every target              | Node kubelet versions                                |
| [kube-proxy version skew](#kube-proxy-version-skew)                               | Every target              | kube-proxy DaemonSet images                          |
| [Node cgroup compatibility](#node-cgroup-compatibility)                           | Kubernetes 1.35+          | Kubelet cgroup metrics                               |
| [Container runtime support](#container-runtime-support)                           | Kubernetes 1.36+          | Node runtime versions and kubelet metrics            |
| [Node drain feasibility](#node-drain-feasibility)                                 | Every target              | PDB status, active Pods, and Pod volumes             |
| [Admission webhook readiness and safety](#admission-webhook-readiness-and-safety) | Every target              | Webhook configurations, Services, and EndpointSlices |
| [CRD conversion webhook readiness](#crd-conversion-webhook-readiness)             | Every target              | CRDs, Services, and EndpointSlices                   |
| [Aggregated APIService readiness](#aggregated-apiservice-readiness)               | Every target              | Delegated APIService `Available` conditions          |
| [Strict source IP/CIDR validation](#strict-source-ipcidr-validation)              | Kubernetes 1.36+          | Helm and kubectl source manifests                    |
| [GKE exec probe timeout exposure](#gke-exec-probe-timeout-exposure)               | GKE, Kubernetes 1.35+     | Workload exec probes and recent Events               |
| [gitRepo volume driver disabled](#gitrepo-volume-driver-disabled)                 | Kubernetes 1.36+          | Pod and workload volume specs                        |
| [FlexVolume upgrade exposure](#flexvolume-upgrade-exposure)                       | Kubernetes 1.36+, kubeadm | Nodes, workload sources, and PersistentVolumes       |
| [Service externalIPs deprecation](#service-externalips-deprecation)               | Kubernetes 1.36+          | Live Services                                        |
| [Renamed Kubernetes metrics](#renamed-kubernetes-metrics)                         | Kubernetes 1.36+          | PrometheusRule expressions                           |

### Control plane version sequence

**Evidence:** the detected control-plane version and selected target. Radar blocks direct major-version jumps and targets that skip required minor upgrades. A next-minor target passes.

This is a policy check, not proof that the provider offers a specific patch release. Select the next supported minor, upgrade in sequence, and run Upgrade impact again for each step. See the [Kubernetes version skew policy](https://kubernetes.io/releases/version-skew-policy/).

### Removed API usage

**Evidence:** `apiserver_requested_deprecated_apis` series exposed by one API server process. Requests for an API removed by or before the target are **Blocked**. Unavailable metrics make the check **Incomplete**.

A pass covers only the sampled API server process since its last restart. It is not cluster-wide history and does not identify the calling client. Use audit logs to find the user agent, then move it to the replacement API. See the [Kubernetes deprecated API migration guide](https://kubernetes.io/docs/reference/using-api/deprecation-guide/).

### Source manifest API versions

**Evidence:** rendered manifests stored with readable Helm releases and `kubectl.kubernetes.io/last-applied-configuration` annotations fetched directly from common workload and networking resources, including Ingresses, HorizontalPodAutoscalers, and PodDisruptionBudgets. APIs removed by the target are **Blocked**; APIs only deprecated by the target require **Review**.

The check is **Incomplete** when Radar cannot read enough original source to rule out a later Helm upgrade, GitOps reconciliation, or `kubectl apply` submitting an incompatible version. Update the source manifest to the documented replacement and apply it before upgrading. See the [Kubernetes deprecated API migration guide](https://kubernetes.io/docs/reference/using-api/deprecation-guide/).

### Node readiness

**Evidence:** the live `Ready` condition on every readable Node. Existing NotReady nodes are a **Warning** because they are concrete unhealthy state that reduces capacity and makes upgrade-related disruption harder to distinguish from a pre-existing failure. Unreadable Nodes make the check **Incomplete**.

Restore each affected node to Ready or remove it from the cluster before starting the upgrade. This check does not inspect provider control-plane health. See [Node status](https://kubernetes.io/docs/reference/node/node-status/).

### Kubelet version skew

**Evidence:** `status.nodeInfo.kubeletVersion` on readable Nodes. A kubelet older than the target control plane supports, or newer than the target, is **Blocked**. Missing Nodes or an unparseable version makes the affected coverage **Incomplete**.

Upgrade node kubelets into the supported range before moving the control plane. Provider-specific support can be narrower than the upstream policy. See the [kubelet version skew policy](https://kubernetes.io/releases/version-skew-policy/#kubelet).

### kube-proxy version skew

**Evidence:** container images on detected kube-proxy DaemonSets. Unsupported versions are **Blocked**; an image whose version cannot be parsed is **Incomplete**. The check is **Not applicable** when kube-proxy is replaced, provider-managed, or not exposed as a DaemonSet.

Upgrade kube-proxy as part of the cluster upgrade sequence. Radar cannot validate a hidden provider-managed installation. See the [kube-proxy version skew policy](https://kubernetes.io/releases/version-skew-policy/#kube-proxy).

### Node cgroup compatibility

**Applies from:** Kubernetes 1.35.

**Evidence:** the `kubelet_cgroup_version` metric from readable Linux nodes. A node still using cgroup v1 is **Blocked** because Kubernetes 1.35 defaults the kubelet to fail on cgroup v1. An explicit temporary override exists, so this result does not claim that every 1.35 kubelet binary is categorically unable to start. If Radar cannot obtain authoritative cgroup metrics, the check is **Incomplete** rather than assuming cgroup v2.

Replace or reconfigure affected nodes with an operating system and container runtime using cgroup v2 before upgrading. See the [Kubernetes kubelet metrics reference](https://kubernetes.io/docs/reference/instrumentation/metrics/#kubelet_cgroup_version), [Kubernetes 1.35 cgroup v1 change](https://kubernetes.io/blog/2025/12/17/kubernetes-v1-35-release/#removal-of-cgroup-v1-support), and [cgroup v2 guidance](https://kubernetes.io/docs/concepts/architecture/cgroups/).

### Container runtime support

**Applies from:** Kubernetes 1.36.

**Evidence:** the kubelet `kubelet_cri_losing_support` metric. A metric series whose reported support-loss version is reached by the target is **Blocked**. If Radar cannot obtain this authoritative metric, the check is **Incomplete** because the runtime version string alone does not establish Kubernetes compatibility.

Upgrade affected nodes to a runtime version supported by the target before upgrading Kubernetes. Radar does not apply a blanket containerd major-version cutoff or infer compatibility from an unfamiliar runtime name. See the [`kubelet_cri_losing_support` metric](https://kubernetes.io/docs/reference/instrumentation/metrics/#kubelet_cri_losing_support), [Kubernetes CRI support guidance](https://kubernetes.io/blog/2025/09/12/kubernetes-v1-34-cri-cgroup-driver-lookup-now-ga/), and [Kubernetes 1.36 urgent upgrade notes](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.36.md#urgent-upgrade-notes).

### Node drain feasibility

**Evidence:** PodDisruptionBudget selectors and authoritative status, active Pods, Pod readiness, and Pod volumes. A Pod selected by multiple PDBs is **Blocked** because the Kubernetes Eviction API rejects its eviction. A current PDB with `disruptionsAllowed: 0` is also **Blocked** when the default eviction-based drain cannot evict a selected Pod. Overlap detection remains valid when PDB controller status is stale because it depends on selectors; stale status still makes the separate disruption-budget calculation **Incomplete**. An unhealthy-only selection with `unhealthyPodEvictionPolicy: AlwaysAllow` does not block. An active bare Pod is a **Warning** because a normal drain requires `--force` and the Pod will not be recreated. `emptyDir` usage requires **Review** because discarding node-local data is intent-dependent; Radar emits one finding per Pod even when it has multiple `emptyDir` volumes.

Narrow overlapping selectors so each Pod is covered by one PDB, and adjust workload replicas or the remaining PDB until at least one disruption is allowed. Move bare Pods under a controller and confirm whether `emptyDir` data can be discarded. Radar does not perform a drain or simulate provider surge capacity. See [PodDisruptionBudgets](https://kubernetes.io/docs/tasks/run-application/configure-pdb/) and [safe node draining](https://kubernetes.io/docs/tasks/administer-cluster/safely-drain-node/).

### Admission webhook readiness and safety

**Evidence:** ValidatingWebhookConfiguration and MutatingWebhookConfiguration resources, their referenced Services, and ready EndpointSlice endpoints. A missing or endpoint-less Service with `failurePolicy: Fail` is a **Fail-closed webhook backend unavailable** blocker; the same concrete backend failure with `Ignore` is a **Fail-open webhook backend unavailable** warning because admission bypasses the intended policy. `matchPolicy: Exact` appears as **Exact API version matching**, while rules matching TokenReview or SubjectAccessReview appear as **Authentication review interception**. Both require **Review** because their safety depends on the webhook's intended scope. Missing authoritative configuration, Service, or endpoint evidence makes the check **Incomplete**; configuration-only Review findings still appear when backend evidence cannot be read, while Radar does not infer that an unreadable backend is down.

Restore unavailable backends before upgrading. Prefer `matchPolicy: Equivalent`, narrowly scope webhooks away from critical resources and namespaces such as `kube-system` and `kube-node-lease`, and use `failurePolicy: Ignore` where failing open is safe. System-namespace scope is remediation guidance, not an automatic Review finding. Radar verifies reachability from Kubernetes objects, not TLS handshakes or application behavior. See [admission webhook good practices](https://kubernetes.io/docs/concepts/cluster-administration/admission-webhooks-good-practices/) and [dynamic admission control](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/).

### CRD conversion webhook readiness

**Evidence:** CustomResourceDefinitions using webhook conversion, their referenced Services, and ready EndpointSlice endpoints. A missing Service or Service with no ready endpoint is **Blocked** when the CRD has a served non-storage version or a non-storage `status.storedVersions` entry, proving that conversion can be needed. The same concrete backend failure is a **Warning** when no current conversion path is evident. A URL-based conversion webhook requires **Review** because Radar cannot establish its external reachability. Unreadable CRD, Service, or endpoint evidence makes the check **Incomplete**; URL and malformed-configuration findings remain visible when in-cluster backend evidence is unavailable. Clusters without conversion webhooks are **Not applicable**.

Restore the in-cluster conversion Service and its ready endpoints before upgrading. Review URL-based webhook DNS, TLS, and control-plane network access manually. Radar does not call conversion webhooks. See [CRD webhook conversion](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definition-versioning/#webhook-conversion).

### Aggregated APIService readiness

**Evidence:** the `Available` condition on delegated `APIService` resources whose `spec.service` points to an extension API server. `Available: False` or `Unknown` is a **Warning** because the Kubernetes aggregation layer concretely reports that it cannot currently serve that API. A missing or malformed `Available` condition makes the check **Incomplete**. Clusters without delegated APIServices are **Not applicable**; locally served registrations without `spec.service` are excluded.

Restore the backing Service and endpoints, then resolve aggregation or TLS errors until the APIService reports `Available: True`. Radar deliberately also surfaces unavailable APIServices in its ongoing Issues view: Upgrade impact repeats the fact as a point-in-time preflight with explicit evidence coverage. It does not call the extension API or prove end-to-end behavior. See the [Kubernetes API aggregation layer](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/apiserver-aggregation/) and [`APIService` API](https://kubernetes.io/docs/reference/kubernetes-api/apiregistration/api-service-v1/).

### Strict source IP/CIDR validation

**Applies from:** Kubernetes 1.36.

**Evidence:** original object definitions recovered from readable Helm release manifests and kubectl last-applied configuration. Non-canonical or otherwise invalid IP and CIDR values require **Review** because stricter validation can reject a future update even when an existing stored object continues working under validation ratcheting. Missing original source makes the check **Incomplete**.

Replace affected values with canonical IP addresses or network CIDRs in the source manifest before its next apply. Findings are review items, not blockers, because the live object can remain accepted until the affected field is changed. Radar checks only the legacy authored fields enumerated by the upstream enhancement, not arbitrary strings or already-strict fields. See [KEP-4858: stricter IP/CIDR validation](https://github.com/kubernetes/enhancements/tree/master/keps/sig-network/4858-ip-cidr-validation) and the [Kubernetes 1.36 urgent upgrade notes](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.36.md#urgent-upgrade-notes).

### GKE exec probe timeout exposure

**Applies from:** Kubernetes 1.35 on GKE. Other providers are **Not applicable**.

**Evidence:** exec-based liveness, readiness, and startup probes plus recent Kubernetes Events. A matching timeout Event, including the upstream `probe failed: command timed out` message, appears as **Exec probe already timing out** and is **Blocked**. An exec probe with omitted `timeoutSeconds`, which defaults to one second, appears as **Exec probe relies on default one-second timeout** and requires **Review**. Even an explicit longer timeout is **Incomplete** without duration evidence because Kubernetes Events are short-lived and static configuration cannot prove the command finishes in time.

Set a timeout that safely exceeds normal command duration and test the probe before upgrading. Kubernetes Events are short-lived, so a clean scan is only evidence for the retained event window. See [GKE exec probe timeout preparation](https://cloud.google.com/kubernetes-engine/docs/deprecations/exec-probe-timeouts).

### gitRepo volume driver disabled

**Applies from:** Kubernetes 1.36.

**Evidence:** Pod specs across Pods, Deployments, ReplicaSets, StatefulSets, DaemonSets, Jobs, and CronJobs. Any `gitRepo` volume is **Blocked** because Kubernetes 1.36 disables the volume driver by default with no option to turn it back on, so affected Pods cannot start. Unreadable workload kinds make the check **Incomplete**.

Clone the repository into an `emptyDir` from an init container, then mount that volume into the workload containers. See the [gitRepo volume migration guidance](https://kubernetes.io/docs/concepts/storage/volumes/#gitrepo) and [Kubernetes 1.36 removal announcement](https://kubernetes.io/blog/2026/04/22/kubernetes-v1-36-release/#removal-of-the-gitrepo-volume-driver).

### FlexVolume upgrade exposure

**Applies from:** Kubernetes 1.36 on kubeadm-managed control planes. Managed control planes are **Not applicable**.

**Evidence:** Nodes determine whether the cluster uses a kubeadm-managed control plane; FlexVolume sources come from readable workload Pod specs and PersistentVolumes. Radar distinguishes **Workload uses a FlexVolume volume** from **PersistentVolume uses FlexVolume** so each issue type has its own affected-resource list. Both are a **Warning** because kubeadm no longer configures FlexVolume support automatically, while Radar cannot prove whether custom controller-manager compatibility setup is present. Missing Node evidence makes applicability **Incomplete** because Radar cannot distinguish kubeadm from a managed control plane. Missing workload or PersistentVolume evidence also makes the check **Incomplete**.

Migrate to a CSI driver, or verify the required custom kube-controller-manager image, flag, and mount before upgrading. See the [Kubernetes 1.36 urgent upgrade notes](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.36.md#urgent-upgrade-notes).

### Service externalIPs deprecation

**Applies from:** Kubernetes 1.36.

**Evidence:** `spec.externalIPs` on readable Services. Matches require **Review** because the field is deprecated and planned for future disablement. Unreadable Services make the check **Incomplete**.

Move exposure to a LoadBalancer Service, Gateway API, or another implementation with explicit administrative control. This check does not flag Node ExternalIP addresses or the displayed external address of a LoadBalancer Service. See the [Service externalIPs deprecation announcement](https://kubernetes.io/blog/2026/05/14/kubernetes-v1-36-deprecation-and-removal-of-service-externalips/).

### Renamed Kubernetes metrics

**Applies from:** Kubernetes 1.36.

**Evidence:** expressions in readable Prometheus Operator PrometheusRules. Rules referencing `volume_operation_total_errors` or `etcd_bookmark_counts` are a **Warning** because those exact series are renamed and the affected expression will stop receiving data. Missing readable rules make the check **Incomplete**; a cluster without PrometheusRule installed is **Not applicable**.

Replace the old metric with `volume_operation_errors_total` or `etcd_bookmark_total` before upgrading. Radar does not inspect alert definitions stored outside PrometheusRule resources. See the [Kubernetes 1.36 urgent upgrade notes](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.36.md#urgent-upgrade-notes).

## Evidence and coverage

### The scan is cluster-wide within your permissions

The namespace picker in Radar's header is a browsing filter. It does not narrow upgrade analysis. Upgrade impact evaluates every namespace the current identity can read.

The scan still respects every real boundary:

* With authentication enabled, namespaced evidence is limited to the signed-in user's Kubernetes RBAC.
* `--namespace-scope` remains a hard cache boundary and is intersected with the user's access.
* Cluster-scoped Nodes and PersistentVolumes are included only when the user can list them.
* Cluster-scoped admission webhook configurations and CustomResourceDefinitions are included only when the user can list them.
* PodDisruptionBudgets, Events, Services, and EndpointSlices follow per-namespace read permissions. Missing endpoint or event access is reported as incomplete evidence where it affects a check.
* Helm manifests are read only from namespaces where the user can list the release Secrets. A denied namespace becomes an explicit coverage caveat instead of hiding the other readable namespaces.
* PrometheusRules follow API discovery and per-namespace read permissions.
* Kubelet metrics used for cgroup and runtime checks are included only where the cluster and current identity expose them. Radar does not convert missing node metrics into a pass.
* If the identity cannot inspect any namespace, Radar shows one no-access state rather than an empty green result.

### Clean API metrics are sampled evidence

The removed-API check reads Kubernetes API server metrics. A clean result covers **one API server process over its observed process lifetime**. It does not prove cluster-wide history across replicas or earlier restarts.

Radar shows that lifetime in the row summary and repeats the limitation in the expanded evidence scope. If metrics cannot be read, the check is **Incomplete**, not Passed.

### Source manifests matter more than live object versions

The API version on a live object is not reliable proof of the version originally submitted. Kubernetes can convert and store objects at a preferred version.

Radar therefore checks sources that preserve submission intent:

* the rendered manifest stored with each readable Helm release;
* `kubectl.kubernetes.io/last-applied-configuration` on live objects.

If neither source is available, Radar cannot rule out a future Helm upgrade, `kubectl apply`, or GitOps reconciliation submitting a removed API or invalid IP/CIDR value. The applicable source-based checks become **Incomplete**.

### Catalog coverage is versioned

The page reports the Kubernetes minor through which the bundled check catalog has been reviewed. The current catalog is reviewed through **Kubernetes 1.36**.

If you select a newer target, Radar still shows known results, but the overall verdict remains coverage-incomplete because release-specific checks added after 1.36 are not included. Update Radar when a build with coverage for that target is available, then run the scan again.

## Permissions

Radar degrades each check independently when evidence is unavailable. For the broadest result, the running identity needs read access to:

* common workloads, Pods, Services, Ingresses, HorizontalPodAutoscalers, EndpointSlices, DaemonSets, Nodes, PersistentVolumes, PodDisruptionBudgets, and Events;
* ValidatingWebhookConfigurations, MutatingWebhookConfigurations, CustomResourceDefinitions, and APIService resources;
* Helm release Secrets if you want stored Helm manifest coverage;
* `PrometheusRule` resources when the Prometheus Operator CRD is installed;
* the API server `/metrics` endpoint for observed deprecated-API requests;
* kubelet metrics for authoritative cgroup mode and container runtime support evidence, where the cluster exposes them.

The in-cluster chart grants read access to the common built-in resources and the upgrade-impact cluster-scoped resources. Radar Cloud's default cluster-read add-on also grants the signed-in tier read access to CRDs, admission webhooks, enabled APIServices, and PrometheusRules. PrometheusRule support follows the default `rbac.crdGroups.prometheus` setting.

The broader API server `/metrics` endpoint and kubelet proxy access remain opt-in in Radar Cloud. Checks that depend on either source show **Incomplete** until an operator explicitly grants that evidence to the user's Cloud tier. Secret access is also opt-in through Helm visibility, Secret visibility, authentication, or Cloud-related chart settings. See [In-cluster deployment](/docs/configuration/in-cluster) and [Authentication](/docs/configuration/authentication) for the surrounding RBAC model.

## API

The same read-only result is available over HTTP:

```bash theme={null}
curl 'http://127.0.0.1:9280/api/upgrade-readiness?target=1.36'
```

The response includes `currentVersion`, `targetVersion`, `reviewedThrough`, the overall `verdict`, summary counts, per-check findings, and coverage metadata. Omit `target` to scan the next Kubernetes minor.

## Current limitations

* API request evidence is not aggregated across API server replicas or retained across restarts.
* Kubernetes Events are short-lived. A clean GKE exec-probe result covers only Events still retained by the cluster.
* Source-manifest coverage comes from Helm storage and kubectl last-applied annotations. Radar does not clone or inspect Git repositories directly.
* Source IP/CIDR validation cannot assess original configuration when neither a Helm manifest nor kubectl last-applied annotation is available.
* Drain feasibility is a static preflight. Radar does not cordon or drain a node, perform a full scheduling simulation, or prove that surge capacity is available.
* Webhook checks validate Kubernetes references and ready endpoints. They do not perform a TLS handshake, call the webhook, or prove that an external URL is reachable from every API server.
* APIService readiness uses the aggregation layer's reported condition. Radar does not call each extension API or prove that every API operation works.
* Provider-managed components can be hidden from the workload APIs; affected checks say **Not applicable** or **Incomplete** rather than guessing.
* Upgrade impact does not validate provider quotas, subnet capacity, managed add-on compatibility, control-plane health, credentials, resource locks, or maintenance windows.
* Upgrade impact does not execute, schedule, pause, or block the provider's upgrade operation.

## See also

* [Cluster audit](/docs/features/cluster-audit) - ongoing security, reliability, and efficiency posture checks.
* [Access control](/docs/features/access-control) - understand which evidence the current identity can read.
* [Helm](/docs/features/helm) - inspect and update the releases that supply source-manifest evidence.
