microsoft/aspire · error · DistributedApplicationException
Stopped waiting for resource
Error message
Stopped waiting for resource '{resourceName}' to become healthy because it failed to start. What it means
Thrown by WaitForResourceHealthyAsync when a resource being waited on reaches the end of its start attempt in a state other than Healthy (e.g. FailedToStart, Exited, Finished). The library stops waiting instead of blocking indefinitely and surfaces a DistributedApplicationException so the app model fails fast with a clear reason.
Solutions
- Inspect the resource's logs in the Aspire dashboard to find why it failed to start (missing env var, bad image, crash).
- Fix the resource configuration (image tag, connection string, bindings) so it can become healthy.
- If the resource legitimately exits after work (batch job), use WaitForCompletion with an expected exit code instead of WaitForResourceHealthy.
- Ensure required dependencies are ordered with WithReference so they start before the failing resource.
- Wrap the AppHost startup/wait in try-catch on DistributedApplicationException when failure is an expected runtime condition.
Example fix
// before
builder.AddProject<Projects.Api>("api")
.WaitForResourceHealthy("db");
// after (db is a one-shot migrator job, so wait for successful completion instead)
builder.AddProject<Projects.Api>("api")
.WaitForCompletion("db", exitCode: 0); Defensive patterns
Strategy: try-catch
Validate before calling
// Verify the dependency exposes health checks before waiting on 'healthy'
if (resourceBuilder.Resource is IResourceWithHealthCheck)
{
builder.WaitForResourceHealthy(resourceBuilder.Resource.Name);
} Try / catch
try
{
await app.StartAsync();
}
catch (DistributedApplicationException ex) when (ex.Message.Contains("failed to start"))
{
logger.LogError(ex, "Dependency failed to start; check dashboard logs.");
} Prevention
- Add health checks/health endpoints to resources before waiting on 'healthy'.
- Fix container images and env config so resources can start reliably.
- Use WaitForCompletion for one-shot jobs instead of health waits.
- Check the dashboard resource logs first when diagnosing.
When it happens
Trigger: Calling builder.CreateResourceBuilder(resource).WaitForResourceHealthy(name) (or the public WaitForResourceHealthyAsync) while the target resource transitions to FailedToStart, Exited, Finished, or RuntimeUnhealthy instead of Healthy.
Common situations: Container image cannot be pulled or crashes at startup; connection strings or env vars invalid so the child app dies during boot; dependency database not ready so the resource's own startup health checks fail; port conflicts.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Circular dependency detected
- ConnectionStringAvailableEvent published for resource
- Resource ' ' stopped waiting for dependency resource ' '…
- Resource ' ' stopped waiting for dependency resource ' '…
- The Aspire orchestration component is not installed at
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/d184264e0f6c7a21.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting/ApplicationModel/ResourceNotificationService.cs:266
var appModel = _serviceProvider.GetService<DistributedApplicationModel>();
if (appModel is not null && !appModel.Resources.Any(r => string.Equals(r.Name, resourceName, StringComparisons.ResourceName)))
{
_logger.LogError("Stopped waiting for resource '{ResourceName}' to become healthy because it does not exist in the application model.", resourceName);
throw new DistributedApplicationException($"Stopped waiting for resource '{resourceName}' to become healthy because it does not exist in the application model.");
}
}
var resourceEvent = await WaitForResourceCoreAsync(
resourceName,
re => ShouldYieldHealthyWait(waitBehavior, re.Snapshot),
$"Resource '{resourceName}' failed to become healthy before the operation was cancelled.",
waitCondition: "healthy",
cancellationToken: cancellationToken).ConfigureAwait(false);
if (resourceEvent.Snapshot.HealthStatus != HealthStatus.Healthy)
{
_logger.LogError("Stopped waiting for resource '{ResourceName}' to become healthy because it failed to start.", resourceName);
throw new DistributedApplicationException($"Stopped waiting for resource '{resourceName}' to become healthy because it failed to start.");
}
// Now wait for the resource ready event to be executed (matching behavior of WaitUntilHealthyAsync).
_logger.LogDebug("Waiting for resource ready to execute for '{ResourceName}'.", resourceName);
resourceEvent = await WaitForResourceCoreAsync(
resourceName,
re => re.ResourceId == resourceEvent.ResourceId && re.Snapshot.ResourceReadyEvent is not null,
$"Resource '{resourceName}' failed to execute the resource ready event before the operation was cancelled.",
waitCondition: "resource_ready",
cancellationToken: cancellationToken).ConfigureAwait(false);
// Observe the result of the resource ready event task
await resourceEvent.Snapshot.ResourceReadyEvent!.EventTask.WaitAsync(cancellationToken).ConfigureAwait(false);
_logger.LogDebug("Finished waiting for resource '{ResourceName}'.", resourceName);
return resourceEvent;
}View on GitHub (pinned to 25830f84bd)