microsoft/aspire · error
No Azure deployment state was found for AKS environment
Error message
No Azure deployment state was found for AKS environment '{Name}'. Cluster cleanup cannot run without an isolated kubeconfig. What it means
During AKS environment destroy, GetAksCredentialsForDestroyAsync reads the persisted 'Azure:Deployments:<Name>' state section to recover the deployed cluster's resource id so it can fetch a kubeconfig and clean up the cluster. This error is thrown when the state store has no deployment outputs for this environment, so cleanup cannot proceed safely with an isolated kubeconfig.
Solutions
- Deploy the environment at least once successfully before destroying, so the deployment state is persisted
- Ensure the destroy command targets the same environment name used during deployment (check 'Azure:Deployments:<Name>' key)
- Restore or point the destroy run at the correct deployment state store/backend used by the original deployment
- If the cluster exists but state is unrecoverable, delete the resource group/cluster directly in Azure instead of through the pipeline cleanup step
Example fix
// before (destroy with mismatched name)
builder.AddAzureKubernetesEnvironment("prod-aks"); // deployed as "aks-env"
// after
builder.AddAzureKubernetesEnvironment("aks-env"); // same name as the deployed state Defensive patterns
Strategy: validation
Validate before calling
var section = await deploymentStateManager.AcquireSectionAsync($"Azure:Deployments:{Name}", ct);
bool canDestroy = section.Data.Count > 0; Try / catch
try
{
await pipeline.DestroyAsync(...);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("No Azure deployment state"))
{
// No prior deployment state; clean up in Azure directly (resource group deletion) instead.
} Prevention
- Only run destroy for environments that completed a successful deployment under the same name
- Never delete or hand-edit the deployment state store between deploy and destroy
- Use the same Aspire CLI/SDK version and state backend for deploy and destroy
- Name AKS environment resources stably; renaming invalidates the state key
When it happens
Trigger: Running aspire destroy / pipeline destroy for an AKS environment whose name has no 'Azure:Deployments:<Name>' section in the deployment state store — e.g. the deployment never completed, the state was deleted, or the environment name doesn't match the one used at deploy time.
Common situations: Destroying an environment that was never successfully deployed; a stale or cleared state store (local state files removed, different state backend); renaming the AKS environment resource between deploy and destroy.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- The Azure deployment state for AKS environment
- The Azure deployment state for AKS environment
- Azure destroy step for environment
- The Azure deployment state for AKS environment
- The persisted scope is not a JSON object.
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/6c91cd412aa4f1c6.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.Azure.Kubernetes/AzureKubernetesEnvironmentResource.AksPipeline.cs:373
{
await getCredsTask.FailAsync(
$"Failed to fetch AKS credentials: {ex.Message}",
context.CancellationToken).ConfigureAwait(false);
throw;
}
}
}
private async Task GetAksCredentialsForDestroyAsync(PipelineStepContext context)
{
var deploymentStateManager = context.Services.GetRequiredService<IDeploymentStateManager>();
var deploymentStateSection = await deploymentStateManager
.AcquireSectionAsync($"Azure:Deployments:{Name}", context.CancellationToken)
.ConfigureAwait(false);
if (deploymentStateSection.Data.Count == 0)
{
throw new InvalidOperationException(
$"No Azure deployment state was found for AKS environment '{Name}'. " +
"Cluster cleanup cannot run without an isolated kubeconfig.");
}
// Azure deployment outputs are persisted as a JSON string with the ARM output shape:
// {
// "id": { "type": "String", "value": "/subscriptions/.../managedClusters/aks-abc123" },
// "name": { "type": "String", "value": "aks-abc123" }
// }
// Read it directly because the provisioning step that normally populates Outputs is not
// part of a fresh destroy process.
ResourceIdentifier? clusterResourceId;
try
{
clusterResourceId = GetPersistedAksResourceId(deploymentStateSection.Data);
}
catch (Exception ex) when (ex is not OperationCanceledException)
{View on GitHub (pinned to 25830f84bd)