{"record":{"id":"c8a6eebd5b0f15a9","repo":"microsoft/aspire","slug":"stopped-waiting-for-resource-target-displayname-to-become","errorCode":null,"errorMessage":"Stopped waiting for resource '{target.DisplayName}' to become healthy because it failed to start.","messagePattern":"Stopped waiting for resource '(.+?)' to become healthy because it failed to start\\.","errorType":"exception","errorClass":"DistributedApplicationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting/Backchannel/AuxiliaryBackchannelRpcTarget.cs","lineNumber":687,"sourceCode":"        }\n        catch (DistributedApplicationException ex)\n        {\n            return new WaitForResourceResponse { Success = false, ErrorMessage = ex.Message };\n        }\n    }\n\n    private static async Task<WaitForResourceResponse> WaitForHealthyAsync(ResourceNotificationService notificationService, WaitResourceTarget target, CancellationToken cancellationToken)\n    {\n        var resourceEvent = await WaitForResourceEventAsync(\n            notificationService,\n            target,\n            re => ResourceNotificationService.ShouldYieldHealthyWait(WaitBehavior.StopOnResourceUnavailable, re.Snapshot),\n            $\"Resource '{target.DisplayName}' failed to become healthy before the operation was cancelled.\",\n            cancellationToken).ConfigureAwait(false);\n\n        if (resourceEvent.Snapshot.HealthStatus != HealthStatus.Healthy)\n        {\n            throw new DistributedApplicationException($\"Stopped waiting for resource '{target.DisplayName}' to become healthy because it failed to start.\");\n        }\n\n        resourceEvent = await WaitForResourceEventAsync(\n            notificationService,\n            new WaitResourceTarget(target.DisplayName, resourceEvent.ResourceId, null),\n            re => re.Snapshot.ResourceReadyEvent is not null,\n            $\"Resource '{target.DisplayName}' failed to execute the resource ready event before the operation was cancelled.\",\n            cancellationToken).ConfigureAwait(false);\n\n        await resourceEvent.Snapshot.ResourceReadyEvent!.EventTask.WaitAsync(cancellationToken).ConfigureAwait(false);\n\n        return new WaitForResourceResponse\n        {\n            Success = true,\n            State = resourceEvent.Snapshot.State?.Text,\n            HealthStatus = resourceEvent.Snapshot.HealthStatus?.ToString()\n        };\n    }","sourceCodeStart":669,"sourceCodeEnd":705,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting/Backchannel/AuxiliaryBackchannelRpcTarget.cs#L669-L705","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Inspect the resource state/logs in the Aspire dashboard to find the startup failure cause.","Fix the underlying resource startup error (image name, environment variables, connection strings, command).","Verify health-check endpoints/annotations (WithHealthCheck) are reachable and correctly configured.","Catch DistributedApplicationException in the wait caller and handle the failure gracefully.","Re-run the wait after the resource configuration is corrected."],"exampleFix":"// before\nvar resp = await rpc.WaitForResourceAsync(new WaitForResourceRequest { ResourceName = \"pg\", Status = \"healthy\", TimeoutSeconds = 60 });\n// after\ntry\n{\n    var resp = await rpc.WaitForResourceAsync(new WaitForResourceRequest { ResourceName = \"pg\", Status = \"healthy\", TimeoutSeconds = 60 });\n}\ncatch (DistributedApplicationException ex)\n{\n    logger.LogError(ex, \"Resource failed to start; check dashboard logs.\");\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { var resp = await rpc.WaitForResourceAsync(new WaitForResourceRequest { ResourceName = name, Status = \"healthy\", TimeoutSeconds = 120 }); }\ncatch (DistributedApplicationException ex) { logger.LogError(ex, \"Resource '{Name}' failed to start; inspect dashboard logs.\", name); }","preventionTips":["Fix resource startup config (images, env vars, connection strings) before waiting on health.","Verify health-check annotations point at reachable endpoints.","Handle DistributedApplicationException as an expected failure path in wait automation.","Check the dashboard's resource state/logs for the first failure cause."],"tags":["health","resource-startup","wait"],"backgroundTag":"invalid-state-transition","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}