microsoft/aspire · error · InvalidOperationException

ASPIRERADIUS091

ASPIRERADIUS091

Error message

The Radius control plane in Kubernetes context '{kubeContext}' is v{controlPlaneVersion}, but this integration requires v{MinimumControlPlaneVersion} or later. Deploying to an older control plane appears to succeed while silently discarding the recipe pack, leaving every backing resource without a recipe. Run 'rad upgrade kubernetes' to bring the control plane up to date, then deploy again. Diagnostic: ASPIRERADIUS091.

What it means

VerifyControlPlaneVersionAsync probes the Radius control plane in the target Kubernetes context and throws this error when its version is older than MinimumControlPlaneVersion. The message explains why old control planes are dangerous for Aspire: deploying to them can appear to succeed while the recipe pack is silently discarded, leaving every backing resource without a recipe (diagnostic ASPIRERADIUS091). It instructs running 'rad upgrade kubernetes' before deploying again.

Solutions

  1. Run 'rad upgrade kubernetes' (with the correct kube context) to bring the control plane to a supported version, then deploy again
  2. Verify with 'rad version' that the control plane version meets the integration's minimum
  3. Ensure the kube context you deploy to is the intended, up-to-date one (kubectl config get-contexts / kubectl config use-context)
  4. Update the rad CLI itself first, since upgrades are driven by the CLI's supported chart versions

Example fix

// before: deploying to a stale cluster
rad version  // control plane v0.30 < required

// after: upgrade the control plane, then redeploy
kubectl config use-context my-cluster
rad upgrade kubernetes
rad version  // confirm >= minimum
aspire publish
Defensive patterns

Strategy: validation

Validate before calling

# Verify the control plane version before deploying
rad version  # compare 'control plane' version against the integration minimum
# if outdated:
#   kubectl config use-context <target-context>
#   rad upgrade kubernetes

Try / catch

try
{
    await pipeline.ExecuteAsync(context, ct);
}
catch (Exception ex) when (ex.Message.Contains("ASPIRERADIUS091"))
{
    logger.LogError("Upgrade the Radius control plane with 'rad upgrade kubernetes', then redeploy.");
    throw;
}

Prevention

When it happens

Trigger: Running the Radius deployment pipeline step against a Kubernetes context whose Radius control plane reports a version below the integration's MinimumControlPlaneVersion — detected via rad/publisher version probing of the context's control plane deployment.

Common situations: Long-lived cluster whose Radius control plane was never upgraded after installing a newer Aspire integration; pinning an old rad CLI or old control-plane Helm chart; cluster fleet with mixed Radius versions where an outdated context is targeted; upgrading the Aspire Radius integration (raising MinimumControlPlaneVersion) without upgrading the cluster.

Related errors


AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16). Data as JSON: /api/errors/4262164d4197013c. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Hosting.Radius/Publishing/RadiusDeploymentPipelineStep.cs:221

                cancellationToken).ConfigureAwait(false);

            if (version is not { ExitCode: 0 } versionResult)
            {
                logger.LogDebug("Could not run 'rad version --output json'; skipping the control plane version check.");
                return;
            }

            if (!TryParseControlPlaneVersion(versionResult.StandardOutput, out var controlPlaneVersion) || controlPlaneVersion is null)
            {
                logger.LogDebug(
                    "Could not determine the Radius control plane version in Kubernetes context '{KubeContext}'; skipping the control plane version check.",
                    kubeContext);
                return;
            }

            if (controlPlaneVersion < MinimumControlPlaneVersion)
            {
                throw CreateUnsupportedControlPlaneException(controlPlaneVersion, kubeContext);
            }

            logger.LogInformation(
                "Radius control plane v{ControlPlaneVersion} detected in Kubernetes context '{KubeContext}'.",
                controlPlaneVersion,
                kubeContext);
        }
        finally
        {
            try
            {
                kubeConfigHome.Delete(recursive: true);
            }
            catch (Exception ex) when (ex is IOException or UnauthorizedAccessException)
            {
                // Best effort: a leaked temp kubeconfig must never fail an otherwise valid deploy.
            }
        }

View on GitHub (pinned to 25830f84bd)