microsoft/aspire · error · InvalidOperationException

Resource ' ' has multiple container registries available -…

Error message

Resource '{resource.Name}' has multiple container registries available - '{registryNames}'. Please specify which registry to use with '.WithContainerRegistry(registryBuilder)'.

What it means

When resolving the container image registry for a resource, more than one ContainerRegistryTarget annotation was found. Aspire cannot infer which registry to publish to, so it requires an explicit choice via .WithContainerRegistry().

Solutions

  1. Apply .WithContainerRegistry(registryBuilder) with the single desired registry
  2. Remove duplicate .WithContainerRegistry calls so only one registry target remains
  3. Refactor shared extension helpers so only one adds a container registry

Example fix

// before
var acr = builder.AddAzureContainerRegistry("acr");
resource.WithContainerRegistry(acr);
resource.WithContainerRegistry(localRegistry); // second registry
// after
var acr = builder.AddAzureContainerRegistry("acr");
resource.WithContainerRegistry(acr); // exactly one registry
Defensive patterns

Strategy: validation

Validate before calling

var registries = resource.Annotations.OfType<ContainerRegistryTargetAnnotation>().ToList();
if (registries.Count > 1) { /* choose one explicitly or throw your own clear error */ }

Try / catch

try { var registry = resource.GetContainerRegistry(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("multiple container registries")) { /* apply .WithContainerRegistry and retry */ }

Prevention

When it happens

Trigger: Publishing a containerized resource (GetContainerRegistry / GetRemoteImageName path) while the model contains two or more ContainerRegistryTarget annotations from calls like .WithContainerRegistry() with different registry resources.

Common situations: Applying .WithContainerRegistry twice with different registries, or having multiple registry resources (e.g., ACR plus a local registry) applied across shared extension helpers on the same resource.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


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

Appendix: source

Thrown at src/Aspire.Hosting/ApplicationModel/ResourceExtensions.cs:1386

        // Try to get the container registry from DeploymentTargetAnnotation first
        var deploymentTarget = resource.GetDeploymentTargetAnnotation();
        if (deploymentTarget?.ContainerRegistry is not null)
        {
            return deploymentTarget.ContainerRegistry;
        }

        // Fall back to RegistryTargetAnnotation (added automatically via BeforeStartEvent)
        var registryTargetAnnotations = resource.Annotations.OfType<RegistryTargetAnnotation>().ToArray();
        if (registryTargetAnnotations.Length == 1)
        {
            return registryTargetAnnotations[0].Registry;
        }

        if (registryTargetAnnotations.Length > 1)
        {
            var registryNames = string.Join(", ", registryTargetAnnotations.Select(a => a.Registry is IResource res ? res.Name : a.Registry.ToString()));
            throw new InvalidOperationException(
                $"Resource '{resource.Name}' has multiple container registries available - '{registryNames}'. " +
                $"Please specify which registry to use with '.WithContainerRegistry(registryBuilder)'.");
        }

        throw new InvalidOperationException($"Resource '{resource.Name}' does not have a container registry reference.");
    }

    /// <summary>
    /// Gets the full remote image name for the specified resource, including registry endpoint and tag.
    /// </summary>
    /// <param name="resource">The resource to get the remote image name for.</param>
    /// <param name="cancellationToken">A cancellation token to observe while processing.</param>
    /// <returns>The fully qualified remote image name.</returns>
    /// <exception cref="InvalidOperationException">Thrown when the resource does not have a container registry reference.</exception>
    /// <remarks>
    /// This method processes any image push options callbacks on the resource and combines the result
    /// with the container registry to produce the full remote image name.
    /// </remarks>

View on GitHub (pinned to 25830f84bd)