rancher/rancher · error
kubernetes version of the cluster cannot be determined
Error message
kubernetes version of the cluster cannot be determined
What it means
listKubernetesUpgradeVersions reads the current version from cluster.Spec.AKSConfig.KubernetesVersion, falling back to cluster.Status.AKSStatus.UpstreamSpec.KubernetesVersion. If the spec pointer is nil AND (UpstreamSpec is nil or its KubernetesVersion is nil), the version cannot be determined and a 400 is returned (listers.go:238-240).
Source
Thrown at pkg/api/norman/customization/aks/listers.go:239
}
// listKubernetesUpgradeVersions lists all kubernetes versions listed by AKS Container Service and marks which ones the
// given cluster can be upgraded to. A version's `Enabled` flag is true if the cluster can be upgraded to the version
// in its current state.
func listKubernetesUpgradeVersions(ctx context.Context, clusterLister mgmtv3.ClusterCache, cap *Capabilities) ([]byte, int, error) {
var resp UpgradeVersionsResponse
// load the target cluster, if the cluster is not found we cannot proceed
cluster, err := clusterLister.Get(cap.ClusterID)
if err != nil {
return nil, http.StatusBadRequest, fmt.Errorf("invalid cluster id")
}
if cluster.Spec.AKSConfig.KubernetesVersion != nil {
resp.CurrentVersion = *cluster.Spec.AKSConfig.KubernetesVersion
} else {
if cluster.Status.AKSStatus.UpstreamSpec == nil || cluster.Status.AKSStatus.UpstreamSpec.KubernetesVersion == nil {
return nil, http.StatusBadRequest, fmt.Errorf("kubernetes version of the cluster cannot be determined")
}
resp.CurrentVersion = *cluster.Status.AKSStatus.UpstreamSpec.KubernetesVersion
}
// get the client for aks container service
client, err := NewManagedClustersClient(cap)
if err != nil {
return nil, http.StatusInternalServerError, err
}
res, err := client.ListKubernetesVersions(ctx, cap.ResourceLocation, nil)
if err != nil {
return nil, http.StatusBadRequest, fmt.Errorf("failed to get Kubernetes versions: %w", err)
}
if len(res.Values) == 0 {
return nil, http.StatusBadRequest, fmt.Errorf("no versions were returned: %w", err)
}View on GitHub (pinned to 932558d4e6)
Solutions
- Wait for the AKS operator to sync the cluster, then retry: kubectl get cluster <id> -o yaml should show status.akSStatus.upstreamSpec.kubernetesVersion
- Check aks-operator logs (cattle-system / aks-operator pod) if status stays empty
- Ensure spec.akSConfig.kubernetesVersion is set on provisioned clusters rather than relying on upstream status
Example fix
# before: retry loop fires immediately after registration
# after: poll until version is populated
kubectl get cluster c-m-xxxxx -o jsonpath='{.status.akSStatus.upstreamSpec.kubernetesVersion}'
# retry the GET /v3/aksKubernetesUpgradeVersions call only once this returns non-empty Defensive patterns
Strategy: retry
Validate before calling
// poll the cluster until its version is populated, then call the endpoint
async function untilVersionKnown(clusterId, tries = 12) {
for (let i = 0; i < tries; i++) {
const c = await (await fetch(`/v3/clusters/${clusterId}`)).json();
const v = c.spec?.akSConfig?.kubernetesVersion ?? c.status?.akSStatus?.upstreamSpec?.kubernetesVersion;
if (v) return v;
await sleep(5000);
}
throw new Error('cluster version not populated - check aks-operator');
} Type guard
function clusterVersionKnown(c) {
return !!(c?.spec?.akSConfig?.kubernetesVersion ?? c?.status?.akSStatus?.upstreamSpec?.kubernetesVersion);
} Try / catch
const resp = await fetch(upgradeUrl);
if (resp.status === 400) {
const { error } = await resp.json();
if (/kubernetes version of the cluster cannot be determined/.test(error)) {
await untilVersionKnown(clusterId); await fetch(upgradeUrl); // retry after sync
}
} Prevention
- Gate the upgrade wizard on clusterVersionKnown(cluster) in the UI
- Watch aks-operator health right after registering AKS clusters
- Set spec.akSConfig.kubernetesVersion on provisioned clusters so the spec path is used
When it happens
Trigger: An AKS cluster registered/imported into Rancher whose status has not yet been filled by aks-operator (UpstreamSpec still empty); a cluster object created seconds ago; a cluster whose AKSConfig was reset; in rare cases a cluster whose spec version was explicitly cleared awaiting reconciliation.
Common situations: Opening the upgrade-versions wizard immediately after cluster registration; aks-operator pod crash-looping so UpstreamSpec never populates; Rancher restored from backup with stale cluster status.
Related errors
- must provide clientSecret
- could not find tenant ID for Azure environment %s: %w
- invalid cloud credential ID %s
- cloud credential not found
- error accessing cloud credential %s
AI-assisted analysis of rancher/rancher@932558d4e6 (2026-08-16).
Data as JSON: /api/errors/1d3a09b6e96ca288.
Report an issue: GitHub.