microsoft/aspire · error · DistributedApplicationException

Stopped waiting for resource

Error message

Stopped waiting for resource '{target.DisplayName}' to become healthy because it failed to start.

What it means

When waiting for a resource to become healthy (WaitForResourceAsync with status 'healthy'), the wait ended because the resource reached an unavailable/failed state (WaitBehavior.StopOnResourceUnavailable). Since the final HealthStatus was not Healthy, a DistributedApplicationException is thrown reporting the resource failed to start rather than becoming healthy.

Solutions

  1. Inspect the resource state/logs in the Aspire dashboard to find the startup failure cause.
  2. Fix the underlying resource startup error (image name, environment variables, connection strings, command).
  3. Verify health-check endpoints/annotations (WithHealthCheck) are reachable and correctly configured.
  4. Catch DistributedApplicationException in the wait caller and handle the failure gracefully.
  5. Re-run the wait after the resource configuration is corrected.

Example fix

// before
var resp = await rpc.WaitForResourceAsync(new WaitForResourceRequest { ResourceName = "pg", Status = "healthy", TimeoutSeconds = 60 });
// after
try
{
    var resp = await rpc.WaitForResourceAsync(new WaitForResourceRequest { ResourceName = "pg", Status = "healthy", TimeoutSeconds = 60 });
}
catch (DistributedApplicationException ex)
{
    logger.LogError(ex, "Resource failed to start; check dashboard logs.");
}
Defensive patterns

Strategy: try-catch

Try / catch

try { var resp = await rpc.WaitForResourceAsync(new WaitForResourceRequest { ResourceName = name, Status = "healthy", TimeoutSeconds = 120 }); }
catch (DistributedApplicationException ex) { logger.LogError(ex, "Resource '{Name}' failed to start; inspect dashboard logs.", name); }

Prevention

When it happens

Trigger: WaitForResourceAsync(request.Status="healthy") where the target resource's snapshot yields the healthy wait with a non-Healthy health status — e.g. resource entered FailedToStart, RuntimeUnhealthy, or Disabled state before becoming Healthy.

Common situations: Container image pull failures or bad image tags; app crashes during startup (missing env vars, bad connection strings); health-check endpoints not responding; resource disabled by configuration.

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


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

Appendix: source

Thrown at src/Aspire.Hosting/Backchannel/AuxiliaryBackchannelRpcTarget.cs:687

        }
        catch (DistributedApplicationException ex)
        {
            return new WaitForResourceResponse { Success = false, ErrorMessage = ex.Message };
        }
    }

    private static async Task<WaitForResourceResponse> WaitForHealthyAsync(ResourceNotificationService notificationService, WaitResourceTarget target, CancellationToken cancellationToken)
    {
        var resourceEvent = await WaitForResourceEventAsync(
            notificationService,
            target,
            re => ResourceNotificationService.ShouldYieldHealthyWait(WaitBehavior.StopOnResourceUnavailable, re.Snapshot),
            $"Resource '{target.DisplayName}' failed to become healthy before the operation was cancelled.",
            cancellationToken).ConfigureAwait(false);

        if (resourceEvent.Snapshot.HealthStatus != HealthStatus.Healthy)
        {
            throw new DistributedApplicationException($"Stopped waiting for resource '{target.DisplayName}' to become healthy because it failed to start.");
        }

        resourceEvent = await WaitForResourceEventAsync(
            notificationService,
            new WaitResourceTarget(target.DisplayName, resourceEvent.ResourceId, null),
            re => re.Snapshot.ResourceReadyEvent is not null,
            $"Resource '{target.DisplayName}' failed to execute the resource ready event before the operation was cancelled.",
            cancellationToken).ConfigureAwait(false);

        await resourceEvent.Snapshot.ResourceReadyEvent!.EventTask.WaitAsync(cancellationToken).ConfigureAwait(false);

        return new WaitForResourceResponse
        {
            Success = true,
            State = resourceEvent.Snapshot.State?.Text,
            HealthStatus = resourceEvent.Snapshot.HealthStatus?.ToString()
        };
    }

View on GitHub (pinned to 25830f84bd)