microsoft/aspire · error · DistributedApplicationException
The configured OTLP endpoint URL
Error message
The configured OTLP endpoint URL '{url}' from '{configKey}' must be an absolute locally reachable HTTP or HTTPS URL with a port between 1 and 65535. What it means
ResolveConfiguredOtlpEndpoint reads a user-configured OTLP endpoint URL from configuration (configKey) and validates it in CreateConfiguredOtlpEndpointTarget. The URL must be absolute, HTTP or HTTPS, point at a locally reachable dashboard binding, and have a valid port (1-65535). Any violation throws DistributedApplicationException naming the offending URL and config key.
Solutions
- Set the config key to an absolute URL like http://localhost:PORT or https://localhost:PORT matching the dashboard's actual OTLP endpoint binding.
- Check the config key name in the message is the one you intend; fix typos and ensure only one value is set.
- Verify IsLocalDashboardBinding expectations: use localhost/127.0.0.1 (the locally bound dashboard address), not a remote host.
- Ensure the port is explicit and within 1-65535 — append :PORT if the URL omits it.
Example fix
// before env["DOTNET_DASHBOARD_OTLP_ENDPOINT_URL"] = "tcp://0.0.0.0"; // after env["DOTNET_DASHBOARD_OTLP_ENDPOINT_URL"] = "http://localhost:18889";
Defensive patterns
Strategy: validation
Validate before calling
bool IsValidOtlpUrl(string? url) =>
Uri.TryCreate(url, UriKind.Absolute, out var u) &&
u.Scheme is "http" or "https" &&
(u.Host is "localhost" or "127.0.0.1") &&
u.Port is >= 1 and <= 65535; Type guard
static bool IsAbsoluteLocalHttpUrl(string? s) => Uri.TryCreate(s, UriKind.Absolute, out var u) && u.Scheme is "http" or "https" && u.Port is >= 1 and <= 65535;
Try / catch
try { await startAsync(); } catch (DistributedApplicationException ex) when (ex.Message.Contains("OTLP endpoint URL")) { // fix the config value named in the message } Prevention
- Use absolute http(s)://localhost:PORT URLs for OTLP endpoint config
- Never use 'tcp' scheme or port 0 in OTLP URL config
- Point the URL at the local dashboard binding, not a remote host
- Validate configured env vars in launchSettings/CI before running the AppHost
When it happens
Trigger: Setting the OTLP endpoint configuration key (e.g. an env var like DOTNET_DASHBOARD_OTLP_ENDPOINT_URL or the MAUI-specific config key) to a relative URL, a non-http scheme (tcp), a remote host that fails IsLocalDashboardBinding, or a port of 0/out of range (src/Aspire.Hosting.Maui/MauiOtlpExtensions.cs:252).
Common situations: Typo'd or truncated env values; copying an https URL with a wrong/remote host into a local-run scenario; using the gRPC 'tcp' scheme out of habit; port 0 or empty port in the configured URL; CI containers where the dashboard binds to an unexpected host.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- The Aspire dashboard resource
- The MAUI OTLP dev tunnel configuration was not initialized…
- The MAUI OTLP dev tunnel configuration was not initialized…
- The MAUI OTLP endpoint could not be determined within
- A BlobServiceClient could not be configured. Ensure valid…
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/f8da49e3903fe905.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.Maui/MauiOtlpExtensions.cs:252
if (string.IsNullOrWhiteSpace(configuredGrpcUrl) && string.IsNullOrWhiteSpace(configuredHttpUrl))
{
return null;
}
return !string.IsNullOrWhiteSpace(configuredHttpUrl)
? CreateConfiguredOtlpEndpointTarget(configuredHttpUrl, KnownConfigNames.DashboardOtlpHttpEndpointUrl, OtlpHttpProtobufProtocol)
: CreateConfiguredOtlpEndpointTarget(configuredGrpcUrl!, KnownConfigNames.DashboardOtlpGrpcEndpointUrl, OtlpGrpcProtocol);
}
private static OtlpEndpointTarget CreateConfiguredOtlpEndpointTarget(string url, string configKey, string protocol)
{
if (!Uri.TryCreate(url, UriKind.Absolute, out var uri) ||
uri.Scheme is not ("http" or "https") ||
!IsLocalDashboardBinding(uri) ||
uri.Port is < 1 or > 65535)
{
throw new DistributedApplicationException($"The configured OTLP endpoint URL '{url}' from '{configKey}' must be an absolute locally reachable HTTP or HTTPS URL with a port between 1 and 65535.");
}
return new OtlpEndpointTarget(uri.Scheme, uri.Port, protocol);
}
private static string ResolveDynamicDashboardOtlpScheme(IConfiguration configuration)
=> configuration.GetBool(KnownConfigNames.AllowUnsecuredTransport) is true ? "http" : "https";
private static async ValueTask<OtlpEndpointTarget?> TryResolveDashboardOtlpEndpointAsync(
IResource resource,
IServiceProvider services,
bool waitForRuntimeSnapshot,
TimeSpan runtimeSnapshotResolutionTimeout,
CancellationToken cancellationToken)
{
if (!string.Equals(resource.Name, KnownResourceNames.AspireDashboard, StringComparisons.ResourceName) || resource is not IResourceWithEndpoints dashboardResource)
{
return null;View on GitHub (pinned to 25830f84bd)