{"record":{"id":"fe35336af1d5f05d","repo":"microsoft/aspire","slug":"the-aspire-dashboard-resource-resourcename-did-not-publish-a","errorCode":null,"errorMessage":"The Aspire dashboard resource '{resourceName}' did not publish a concrete OTLP listener within {runtimeSnapshotResolutionTimeout:c}.","messagePattern":"The Aspire dashboard resource '(.+?)' did not publish a concrete OTLP listener within (.+?)\\.","errorType":"exception","errorClass":"DistributedApplicationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.Maui/MauiOtlpExtensions.cs","lineNumber":435,"sourceCode":"        {\n            return null;\n        }\n\n        using var timeoutCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);\n        timeoutCts.CancelAfter(runtimeSnapshotResolutionTimeout);\n\n        ResourceEvent resourceEvent;\n        try\n        {\n            resourceEvent = await notificationService.WaitForResourceAsync(\n                resourceName,\n                resourceEvent => TryResolveDashboardOtlpEndpointFromSnapshot(endpointReference, resourceEvent) is not null ||\n                    IsUnavailableState(resourceEvent.Snapshot.State?.Text),\n                timeoutCts.Token).ConfigureAwait(false);\n        }\n        catch (OperationCanceledException ex) when (!cancellationToken.IsCancellationRequested)\n        {\n            throw new DistributedApplicationException(\n                $\"The Aspire dashboard resource '{resourceName}' did not publish a concrete OTLP listener within {runtimeSnapshotResolutionTimeout:c}.\",\n                ex);\n        }\n\n        return TryResolveDashboardOtlpEndpointFromSnapshot(endpointReference, resourceEvent);\n    }\n\n    private static OtlpEndpointTarget? TryResolveDashboardOtlpEndpointFromSnapshot(\n        EndpointReference endpointReference,\n        ResourceEvent resourceEvent)\n    {\n        if (IsUnavailableState(resourceEvent.Snapshot.State?.Text) ||\n            !endpointReference.Exists ||\n            endpointReference.EndpointAnnotation.AllocatedEndpoint is null)\n        {\n            return null;\n        }\n","sourceCodeStart":417,"sourceCodeEnd":453,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.Maui/MauiOtlpExtensions.cs#L417-L453","documentation":"The Aspire dashboard resource was expected to expose a concrete OTLP (OpenTelemetry Protocol) endpoint, but it never published one in its runtime resource snapshot within the configured timeout. The host waits for a dashboard resource event carrying a usable OTLP listener address and throws a DistributedApplicationException when that wait is cancelled by the timeout (not by caller cancellation).","triggerScenarios":"Calling a MAUI OTLP endpoint/protocol resolution API (e.g., MauiOtlpExtensions) while the dashboard resource fails to start, starts slowly, or publishes only a placeholder (non-concrete) OTLP endpoint within runtimeSnapshotResolutionTimeout.","commonSituations":"Dashboard container image pull delays, dashboard failing to boot due to port conflicts, misconfigured ASPIRE_DASHBOARD_OTLP_ENDPOINT_URL, running on an environment where the dashboard resource is disabled or replaced, or the snapshot event stream never yields a concrete endpoint before the timeout elapses.","solutions":["Increase the runtime snapshot resolution timeout (the runtimeSnapshotResolutionTimeout option) if the dashboard is just slow to start.","Verify the dashboard resource exists in the app model and starts successfully; check dashboard logs for startup errors.","Confirm no port conflicts or firewall rules prevent the dashboard from binding its OTLP listener.","Ensure the environment is not disabling the dashboard (e.g., ASPIRE_ALLOW_UNSECURED_TRANSPORT / dashboard disable settings) when OTLP resolution is required."],"exampleFix":"// before\nvar builder = DistributedApplication.CreateBuilder(args);\n// dashboard slow to start in CI, default timeout too short\n// after\nvar builder = DistributedApplication.CreateBuilder(args);\nbuilder.AddMauiOtlpEndpointResolution(o => o.RuntimeSnapshotResolutionTimeout = TimeSpan.FromMinutes(2));","handlingStrategy":"try-catch","validationCode":"// Before relying on OTLP resolution, confirm the dashboard resource is present\nvar dashboard = appBuilder.Resources.FirstOrDefault(r => r.Name == \"dashboard\");\nif (dashboard is null) throw new InvalidOperationException(\"No dashboard resource; OTLP endpoint cannot be resolved.\");","typeGuard":"bool HasConcreteOtlpEndpoint(ResourceSnapshot snapshot) =>\n    snapshot.Properties?.Any(p => p.Name == \"otlpendpoint\" && !string.IsNullOrEmpty(p.Value?.ToString())) == true;","tryCatchPattern":"try\n{\n    var endpoint = await endpointRef.GetValueAsync(ct);\n}\ncatch (DistributedApplicationException ex) when (ex.Message.Contains(\"did not publish a concrete OTLP listener\"))\n{\n    // fall back to ASPIRE_DASHBOARD_OTLP_ENDPOINT_URL or surface a diagnostics message\n}","preventionTips":["Check dashboard logs for startup failures before waiting on OTLP endpoints","Avoid disabling the dashboard in environments where OTLP endpoint resolution is needed","Set a generous runtime snapshot resolution timeout on slow/CI machines","Watch for port conflicts that keep the dashboard from binding its OTLP listener"],"tags":["otlp","dashboard","timeout","maui"],"backgroundTag":"request-timeout","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"}