microsoft/aspire · error · InvalidOperationException
Failed to retrieve container registry endpoint.
Error message
Failed to retrieve container registry endpoint.
What it means
LoginToRegistryAsync resolves the registry's Endpoint value asynchronously before authenticating with 'az acr login'-style flows; a null endpoint means the login target is unknown, so the library throws InvalidOperationException. The endpoint is normally produced by provisioning outputs (login server URL).
Solutions
- Let standard provisioning populate the endpoint by running through the normal publish/deploy flow rather than invoking login before provisioning completes.
- If constructing the resource manually, assign registry.Endpoint from the provisioning context's container registry endpoint output.
- Verify the Azure environment/subscription setup completed successfully so the login server is available.
- Log or inspect the registry resource's parameter values at login time to see which reference is null.
Example fix
// before
await loginService.LoginAsync(endpoint /* null */, tenantId, credential);
// after
var endpoint = await registry.Endpoint.GetValueAsync(ct) ?? throw new InvalidOperationException("Registry endpoint missing; ensure provisioning completed."); Defensive patterns
Strategy: validation
Validate before calling
var endpoint = await registry.Endpoint.GetValueAsync(ct);
if (string.IsNullOrEmpty(endpoint))
{
throw new InvalidOperationException("Registry endpoint missing; ensure provisioning completed before login.");
} Type guard
bool endpointResolved = await registry.Endpoint.GetValueAsync(ct) is string e && !string.IsNullOrEmpty(e);
Try / catch
try
{
await LoginToRegistryAsync(registry, context);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("registry endpoint"))
{
logger.LogError("Registry endpoint was null; confirm Azure provisioning produced the login server.");
throw;
} Prevention
- Do not invoke registry login before provisioning outputs exist.
- Verify publish steps complete without errors so the login-server output is generated.
- When constructing registry resources manually, always assign the Endpoint parameter.
When it happens
Trigger: Awaiting registry.Endpoint.GetValueAsync yields null because the registry resource's endpoint parameter was never populated, typically when provisioning hasn't run or a custom resource construction skipped the endpoint assignment.
Common situations: Publish/run without completing Azure provisioning so the login-server output is absent; manually constructed registry resources in tests or custom pipelines lacking the Endpoint parameter; typos when wiring endpoint references between resources.
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
- Failed to retrieve container registry information.
- Tenant ID is required for ACR authentication but was not…
- The Azure resource scope value cannot be null.
- A purge task with the name
- A of type cannot be assigned to a BicepValue< >.
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/10c6aca041156f3c.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.Azure.ContainerRegistry/AzureContainerRegistryHelpers.cs:32
/// <summary>
/// Helper methods for Azure Container Registry operations.
/// </summary>
internal static class AzureContainerRegistryHelpers
{
public static async Task LoginToRegistryAsync(IContainerRegistry registry, PipelineStepContext context)
{
var acrLoginService = context.Services.GetRequiredService<IAcrLoginService>();
var tokenCredentialProvider = context.Services.GetRequiredService<ITokenCredentialProvider>();
// Find the AzureEnvironmentResource from the application model
var azureEnvironment = context.Model.Resources.OfType<AzureEnvironmentResource>().FirstOrDefault() ??
throw new InvalidOperationException("AzureEnvironmentResource must be present in the application model.");
var registryName = await registry.Name.GetValueAsync(context.CancellationToken).ConfigureAwait(false) ??
throw new InvalidOperationException("Failed to retrieve container registry information.");
var registryEndpoint = await registry.Endpoint.GetValueAsync(context.CancellationToken).ConfigureAwait(false) ??
throw new InvalidOperationException("Failed to retrieve container registry endpoint.");
var loginTask = await context.ReportingStep.CreateTaskAsync(
new MarkdownString($"Logging in to **{registryName}**"),
context.CancellationToken).ConfigureAwait(false);
await using (loginTask.ConfigureAwait(false))
{
try
{
// Get tenant ID from the provisioning context (always available from subscription)
var provisioningContext = await azureEnvironment.ProvisioningContextTask.Task.ConfigureAwait(false);
var tenantId = provisioningContext.Tenant.TenantId?.ToString()
?? throw new InvalidOperationException("Tenant ID is required for ACR authentication but was not available in provisioning context.");
// Use the ACR login service to perform authentication
await acrLoginService.LoginAsync(
registryEndpoint,
tenantId,
tokenCredentialProvider.TokenCredential,View on GitHub (pinned to 25830f84bd)