microsoft/aspire · error · InvalidOperationException
The dashboard URL is not available.
Error message
The dashboard URL is not available.
What it means
After the app starts, GetDashboardUrlAsync looks up a resource named 'dashboard' in the application model and requires it to expose endpoints. If the model has no such resource or it implements no endpoints, no dashboard URL can be derived and this error is thrown.
Solutions
- Ensure the app is started (await app.StartAsync()) and wait for the dashboard resource to be created before fetching the URL.
- Verify the dashboard resource exists: app.Services.GetRequiredService<DistributedApplicationModel>().Resources.Any(r => r.Name == "dashboard").
- Re-enable the dashboard if it was disabled via configuration.
- Check you are running in run mode (not publish) so the dashboard resource is materialized.
Example fix
// before
var url = await app.GetDashboardUrlAsync();
// after
await app.ResourceNotifications.WaitForResourceAsync("dashboard", KnownResourceStates.Running);
var url = await app.GetDashboardUrlAsync(); Defensive patterns
Strategy: validation
Validate before calling
var model = app.Services.GetRequiredService<DistributedApplicationModel>();
var ready = model.Resources.TryGetByName("dashboard", out var r) && r is IResourceWithEndpoints;
if (!ready)
{
// dashboard resource missing or has no endpoints; wait or bail out
} Type guard
static bool HasDashboardResource(DistributedApplication app) =>
app.Services.GetRequiredService<DistributedApplicationModel>()
.Resources.TryGetByName("dashboard", out var r) && r is IResourceWithEndpoints; Try / catch
try
{
var url = await app.GetDashboardUrlAsync(ct);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("not available"))
{
url = null; // dashboard resource absent from the model
} Prevention
- Call GetDashboardUrlAsync only after StartAsync completes.
- Run in run mode so the dashboard resource is added to the model.
- Do not remove or rename the dashboard resource in custom AppHosts.
When it happens
Trigger: Calling GetDashboardUrlAsync on an app whose DistributedApplicationModel lacks the dashboard resource (added automatically only in run mode with dashboard enabled) or whose dashboard resource has no endpoints registered.
Common situations: Calling before the model is fully built/started; custom AppHosts that suppress or rename the dashboard resource; non-Aspire execution paths (e.g. running via dotnet run without the DCP wiring).
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Dashboard testing is not supported in publish mode.
- The dashboard is not enabled for this application.
- The dashboard URL is not available in publish mode.
- AppHost:ResourceService:ApiKey is not specified in…
- Application did not register an implementation of
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/3ea0e689fa13d332.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.Testing/DistributedApplicationHostingTestingExtensions.cs:95
var applicationOptions = app.Services.GetRequiredService<DistributedApplicationOptions>();
if (applicationOptions.DisableDashboard)
{
throw new InvalidOperationException(Properties.Resources.DashboardDisabledExceptionMessage);
}
ThrowIfNotStarted(app, Properties.Resources.DashboardUrlApplicationNotStartedExceptionMessage);
cancellationToken.ThrowIfCancellationRequested();
await app.ResourceNotifications.WaitForResourceHealthyAsync(
DashboardResourceName,
WaitBehavior.StopOnResourceUnavailable,
cancellationToken).ConfigureAwait(false);
var applicationModel = app.Services.GetRequiredService<DistributedApplicationModel>();
if (!applicationModel.Resources.TryGetByName(DashboardResourceName, out var resource) ||
resource is not IResourceWithEndpoints dashboardResource)
{
throw new InvalidOperationException(Properties.Resources.DashboardUrlUnavailableExceptionMessage);
}
var httpsEndpoint = dashboardResource.GetEndpoint("https");
var httpEndpoint = dashboardResource.GetEndpoint("http");
var dashboardEndpoint = httpsEndpoint.Exists ? httpsEndpoint : httpEndpoint;
if (!dashboardEndpoint.Exists)
{
throw new InvalidOperationException(Properties.Resources.DashboardUrlUnavailableExceptionMessage);
}
var dashboardUrl = await EndpointHostHelpers.GetUrlWithTargetHostAsync(dashboardEndpoint, cancellationToken).ConfigureAwait(false);
if (string.IsNullOrEmpty(dashboardUrl))
{
throw new InvalidOperationException(Properties.Resources.DashboardUrlUnavailableExceptionMessage);
}
var browserToken = app.Services.GetRequiredService<IConfiguration>()["AppHost:BrowserToken"];
if (!string.IsNullOrEmpty(browserToken))View on GitHub (pinned to 25830f84bd)