microsoft/aspire · error · InvalidOperationException

Failed to retrieve container registry information.

Error message

Failed to retrieve container registry information.

What it means

PushImageToRemoteRegistryAsync resolves the target registry's name via IContainerRegistry.Name.GetValueAsync. The registry name is a required ReferenceExpression; when it evaluates to null the helper cannot form the push destination and throws InvalidOperationException('Failed to retrieve container registry information.').

Solutions

  1. Ensure the IContainerRegistry's Name expression references only inputs available at publish time and is non-empty.
  2. Verify the underlying registry resource is correctly configured (name, resource group, subscription) before the push step.
  3. For custom registries, implement Name to return a valid ReferenceExpression rather than null/empty.
  4. Run the push within the normal publish pipeline so provisioning outputs (registry name) have been resolved.

Example fix

// before
var registry = new CustomRegistry(); // Name expression never set
builder.AddRegistry(registry);
// after
var registry = new CustomRegistry();
registry.Name = ReferenceExpression.Create($"{parameters.RegistryName}");
builder.AddRegistry(registry);
Defensive patterns

Strategy: validation

Validate before calling

var name = await registry.Name.GetValueAsync(ctx);
if (string.IsNullOrWhiteSpace(name)) throw new InvalidOperationException("Registry name not configured.");

Type guard

bool IsRegistryConfigured(IContainerRegistry r) => r.Name is not null;

Try / catch

try { await PushAsync(resource, registry, context); } catch (InvalidOperationException ex) when (ex.Message.Contains("Failed to retrieve container registry information")) { context.ReportingStep.Complete(CompletionState.WithError, "Registry information missing; check registry configuration.", false); }

Prevention

When it happens

Trigger: Pushing an image where registry.Name (a ReferenceExpression) evaluates to null — e.g. a custom IContainerRegistry with an unset/empty Name expression, or Azure/AWS registry resources whose name inputs (resource group, account id, env values) were not resolved at that point.

Common situations: Custom IContainerRegistry implementations returning a Name expression built from unresolved publish-time parameters, running push steps outside the expected publish context where registry inputs are absent, misconfigured Azure CDK/provisioning outputs so the registry name output never materializes.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

Thrown at src/Aspire.Hosting/Pipelines/PipelineStepHelpers.cs:109

                    new MarkdownString($"Successfully tagged **{resource.Name}** as `{targetTag}`"),
                    CompletionState.Completed,
                    context.CancellationToken).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                await tagTask.CompleteAsync(
                    new MarkdownString($"Failed to tag **{resource.Name}**: {ex.Message}"),
                    CompletionState.CompletedWithError,
                    context.CancellationToken).ConfigureAwait(false);
                throw;
            }
        }
    }

    private static async Task PushImageToRemoteRegistryAsync(IResource resource, IContainerRegistry registry, PipelineStepContext context)
    {
        var registryName = await registry.Name.GetValueAsync(context.CancellationToken).ConfigureAwait(false)
            ?? throw new InvalidOperationException("Failed to retrieve container registry information.");

        IValueProvider cir = new ContainerImageReference(resource);
        var targetTag = await cir.GetValueAsync(new ValueProviderContext { ExecutionContext = context.ExecutionContext }, context.CancellationToken).ConfigureAwait(false);

        var pushTask = await context.ReportingStep.CreateTaskAsync(
            new MarkdownString($"Pushing **{resource.Name}** to **{registryName}**"),
            context.CancellationToken).ConfigureAwait(false);

        await using (pushTask.ConfigureAwait(false))
        {
            try
            {
                if (targetTag is null)
                {
                    throw new InvalidOperationException($"Failed to get target tag for {resource.Name}");
                }

                var containerImageManager = context.Services.GetRequiredService<IResourceContainerImageManager>();

View on GitHub (pinned to 25830f84bd)