microsoft/aspire · error · DistributedApplicationException
Cannot create the cross-scope ACR pull identity
Error message
Cannot create the cross-scope ACR pull identity '{identityName}' for environment '{builder.Resource.Name}' because a resource with that name already exists. Call 'WithAcrPullIdentity' on the environment to select an existing identity, or use a different resource name. What it means
When WithCrossScopeAcrPullIdentity needs to synthesize a managed identity, it derives the name '{environmentName}-mi' and throws DistributedApplicationException if an Azure resource with that name already exists in the model, because a cross-scope role assignment (BCP139) requires promoting this path to a standalone identity resource. The throw prevents silently attaching to an unrelated resource that happens to share the name.
Solutions
- Use WithAcrPullIdentity on the environment to reference the existing identity instead of creating a new one
- Rename the existing colliding resource (e.g. the manually created identity) so it no longer matches '{envName}-mi'
- Rename the environment resource itself so the derived '{name}-mi' is unique in the model
- Check for duplicate calls to WithCrossScopeAcrPullIdentity on the same-named environment and remove the redundant one
Example fix
// before
var env = builder.AddAzureEnvironment("prod");
env.WithCrossScopeAcrPullIdentity(); // throws if "prod-mi" already exists
// after
var existing = builder.AddAzureUserAssignedIdentity("prod-mi");
env.WithAcrPullIdentity(existing); // bind to the existing identity explicitly Defensive patterns
Strategy: validation
Validate before calling
var identityName = $"{envBuilder.Resource.Name}-mi";
if (envBuilder.ApplicationBuilder.Resources.Any(r => string.Equals(r.Name, identityName, StringComparers.ResourceNameComparer)))
{
// bind to the existing identity instead:
envBuilder.WithAcrPullIdentity(existingIdentity);
} Try / catch
try { envBuilder.WithCrossScopeAcrPullIdentity(); }
catch (DistributedApplicationException ex) { throw new InvalidOperationException("Name collision on derived identity; use WithAcrPullIdentity with an existing identity.", ex); } Prevention
- Grep the AppHost for resources named '{env}-mi' before adding cross-scope identities
- Avoid naming custom identities with the '{environmentName}-mi' convention
- Check for duplicate WithCrossScopeAcrPullIdentity calls on the same environment
When it happens
Trigger: Calling WithCrossScopeAcrPullIdentity on an environment when the app model already contains a resource named '{environment.Resource.Name}-mi' — typically a user-defined identity, another environment with the same name plus '-mi', or a manually created AzureUserAssignedIdentityResource with the colliding name.
Common situations: Two environments in one AppHost generate the same '-mi' suffix name; the developer already created an identity named e.g. 'env-mi' for other purposes; a previous version of the call already added the identity and the code now runs twice.
Understand the failure class
Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.
Related errors
- Existing Azure sandbox group
- POST /oauth2/exchange failed
- Response missing refresh_token.
- The connection string for the resource
- A BlobServiceClient could not be configured. Ensure valid…
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/273d62ebb2444398.
Report an issue: GitHub.
Appendix: source
Thrown at src/Shared/CrossScopeAcrPullIdentityPreparer.cs:122
PipelineStepContext context,
IResourceBuilder<TEnvironment> builder,
Func<AzureUserAssignedIdentityResource, IAcrPullIdentityAnnotation> createIdentityAnnotation,
Action<IResourceBuilder<AzureUserAssignedIdentityResource>>? configureIdentity)
where TEnvironment : IResource, IAzureComputeEnvironmentResource
{
if (!ShouldPrepareIdentity(context.ExecutionContext, builder.Resource) ||
builder.Resource.ContainerRegistry is not AzureContainerRegistryResource registry)
{
return;
}
// A cross-scope role assignment cannot be emitted inline in the environment module (BCP139).
// Promote only this path to a standalone identity so AzureResourcePreparer can emit the
// role assignment as a module scoped to the existing registry.
var identityName = $"{builder.Resource.Name}-mi";
if (context.Model.Resources.TryGetByName(identityName, out _))
{
throw new DistributedApplicationException(
$"Cannot create the cross-scope ACR pull identity '{identityName}' for environment '{builder.Resource.Name}' because a resource with that name already exists. Call 'WithAcrPullIdentity' on the environment to select an existing identity, or use a different resource name.");
}
var identity = new AzureUserAssignedIdentityResource(identityName);
var identityBuilder = builder.ApplicationBuilder.CreateResourceBuilder(identity);
identityBuilder.ConfigureInfrastructure(infrastructure =>
{
// The inline identity uses the environment module's standard tags parameter. Recreate that
// contract on the promoted module so deployment tags and required-tag policies still apply.
var tags = new ProvisioningParameter("tags", typeof(object))
{
Value = new BicepDictionary<string>()
};
infrastructure.Add(tags);
var identity = infrastructure.GetProvisionableResources().OfType<UserAssignedIdentity>().Single();
identity.Tags = tags;
});View on GitHub (pinned to 25830f84bd)