microsoft/aspire · error · InvalidOperationException

Resource ' ' does not have a container registry reference.

Error message

Resource '{resource.Name}' does not have a container registry reference.

What it means

The resource has no ContainerRegistryTarget annotation, so there is no registry from which to compose the remote image name. Publishing to a remote registry requires the resource to be associated with a registry.

Solutions

  1. Call .WithContainerRegistry(registryBuilder) on the resource before publishing
  2. Ensure the registry resource (e.g., AddAzureContainerRegistry) is added to the AppHost and referenced
  3. Check custom extension methods to confirm they propagate the registry annotation

Example fix

// before
var image = resource.GetRemoteImageName();
// after
var acr = builder.AddAzureContainerRegistry("myacr");
resource.WithContainerRegistry(acr);
var image = resource.GetRemoteImageName();
Defensive patterns

Strategy: validation

Validate before calling

var hasRegistry = resource.Annotations.OfType<ContainerRegistryTargetAnnotation>().Any();
if (!hasRegistry) { resource.WithContainerRegistry(acr); }

Try / catch

try { var registry = resource.GetContainerRegistry(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("does not have a container registry")) { /* wire the registry before publishing */ }

Prevention

When it happens

Trigger: Calling GetContainerRegistry (directly or via GetRemoteImageName) during publish on a resource that never had .WithContainerRegistry() applied.

Common situations: Publishing a container resource without wiring it to an Azure Container Registry or other registry resource; forgetting the registry call in a custom extension method.

Understand the failure class

Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.

Related errors


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

Appendix: source

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

            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>
    [Experimental("ASPIREPIPELINES003", UrlFormat = "https://aka.ms/aspire/diagnostics#{0}")]
    internal static async Task<string> GetFullRemoteImageNameAsync(
        this IResource resource,
        CancellationToken cancellationToken)
    {

View on GitHub (pinned to 25830f84bd)