microsoft/aspire · error · InvalidOperationException

ASPIRERADIUS084

ASPIRERADIUS084

Error message

Environment variable '{reference.Key}' on container '{reference.ResourceName}' holds a credential and reads it from the '{RadiusResourceTypes.SecuritySecrets}' resource '{reference.Secret.BicepIdentifier}', but a ConfigureRadiusInfrastructure callback removed that resource. Keep the resource, or set '{reference.Key}' explicitly in the callback. Diagnostic: ASPIRERADIUS084.

What it means

Container environment variables marked as holding credentials are wired to reference a generated Security/secrets resource. If a ConfigureRadiusInfrastructure callback removed that secret resource, the environment variable would have nothing to resolve, producing an invalid deployment, so the builder throws early with ASPIRERADIUS084.

Solutions

  1. Keep the referenced secret resource in the model.
  2. Set the environment variable '{reference.Key}' explicitly (to a literal or your own secret) in the callback instead of removing its source.
  3. If replacing with a custom secret, update the container's environment variable reference to the new secret.

Example fix

// before
callback: b =>
{
    b.RemoveResource("connection-secret"); // container env var still points at it
}

// after
callback: b =>
{
    // keep the resource, or explicitly set the env var:
    // b.SetEnvironmentVariable("frontend", "Connection__Password", mySecretRef);
}
Defensive patterns

Strategy: validation

Validate before calling

// In a callback, only remove resources nothing depends on
var referencedSecrets = model.Resources
    .SelectMany(r => r.Annotations.OfType<EnvironmentReferenceAnnotation>())
    .Select(a => a.SecretName)
    .ToHashSet();
if (referencedSecrets.Contains(candidate.Name))
    throw new InvalidOperationException($"'{candidate.Name}' backs container credential env vars and cannot be removed.");

Try / catch

try { await builder.ExecuteCallbacksAsync(ct); }
catch (InvalidOperationException ex) when (ex.Message.Contains("ASPIRERADIUS084"))
{
    logger.LogError(ex, "Callback removed a secret backing a container credential env var; keep it or set the env var explicitly.");
}

Prevention

When it happens

Trigger: Running ConfigureRadiusInfrastructure callbacks that remove a SecuritySecrets resource still referenced by a container's credential environment variable ('{reference.Key}' on '{reference.ResourceName}').

Common situations: Callbacks that strip all generated secret resources; cleanup loops deleting resources by type without checking references; consolidating secrets into a custom one without repointing the container's env var.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at src/Aspire.Hosting.Radius/Publishing/RadiusInfrastructureBuilder.cs:1074

            // the variable's construct owns the result — last-write-wins, as everywhere else.
            if (reference.Container is null ||
                !liveContainers.Contains(reference.Container) ||
                !reference.Container.Env.TryGetValue(reference.Key, out var currentEnvVar) ||
                // BicepDictionary wraps each entry, so unwrap before comparing construct identity.
                !ReferenceEquals(currentEnvVar?.Value, reference.EnvVar))
            {
                continue;
            }

            // The callback re-pointed the reference itself.
            if (!string.Equals(RenderBicepValue(reference.EnvVar.SecretName), reference.OriginalSecretName, StringComparison.Ordinal))
            {
                continue;
            }

            if (!liveSecrets.Contains(reference.Secret))
            {
                throw new InvalidOperationException(
                    $"Environment variable '{reference.Key}' on container '{reference.ResourceName}' holds a credential " +
                    $"and reads it from the '{RadiusResourceTypes.SecuritySecrets}' resource " +
                    $"'{reference.Secret.BicepIdentifier}', but a ConfigureRadiusInfrastructure callback removed that " +
                    $"resource. Keep the resource, or set '{reference.Key}' explicitly in the callback. " +
                    $"Diagnostic: ASPIRERADIUS084.");
            }

            // Validate the key the variable *currently* carries rather than the one the publisher
            // wrote. A callback can re-point the key alone — leaving SecretName aimed at this
            // generated secret and so passing the guard above — and checking the original key would
            // find it present and publish a `secretKeyRef` naming a key that does not exist. Radius
            // accepts that artifact and the failure surfaces as a pod that never starts.
            //
            // Two shapes are deliberately left alone: a key rendered as a Bicep expression only
            // resolves at deploy time, so there is nothing to compare it against, and a cleared key
            // is already rejected by the SecretName/SecretKey pairing check (ASPIRERADIUS087).
            if (IsBicepExpression(reference.EnvVar.SecretKey) ||
                RenderBicepLiteral(reference.EnvVar.SecretKey) is not { } currentSecretKey)

View on GitHub (pinned to 25830f84bd)