microsoft/aspire · critical · ArgumentException
must contain a local loopback address.
Error message
{KnownConfigNames.ResourceServiceEndpointUrl} must contain a local loopback address. What it means
DashboardServiceHost resolves the resource service endpoint from KnownConfigNames.ResourceServiceEndpointUrl and requires it to be a local loopback address, since the dashboard connects to the AppHost's resource service locally. An ArgumentException is thrown when the configured URL host is not loopback (e.g. a public hostname or LAN IP).
Solutions
- Change ResourceServiceEndpointUrl to a loopback address (127.0.0.1, ::1, or localhost) with the correct port.
- If the AppHost truly runs remotely, tunnel the resource service to localhost (e.g. SSH/VS Code port forwarding) and use the local endpoint.
- Remove the ResourceServiceEndpointUrl override to let the host auto-discover the endpoint from the AppHost.
- Check for typos or stale hostnames in launchSettings/environment configuration.
Example fix
// before // ASPIRE_RESOURCE_SERVICE_ENDPOINT_URL=https://devbox.contoso.com:18975 // after // ASPIRE_RESOURCE_SERVICE_ENDPOINT_URL=http://127.0.0.1:18975 (or tunnel the remote port to localhost)
Defensive patterns
Strategy: validation
Validate before calling
var url = new Uri(Environment.GetEnvironmentVariable("ASPIRE_RESOURCE_SERVICE_ENDPOINT_URL")!);
var loopback = new[] { IPAddress.Loopback, IPAddress.IPv6Loopback };
var isLoopback = url.Host is "localhost" || (IPAddress.TryParse(url.Host, out var ip) && loopback.Contains(ip));
if (!isLoopback) throw new ArgumentException($"{url} must be a loopback address."); Type guard
bool IsLoopback(Uri u) => u.Host == "localhost" || (IPAddress.TryParse(u.Host, out var ip) && (IPAddress.Loopback.Equals(ip) || IPAddress.IPv6Loopback.Equals(ip)));
Try / catch
try { startDashboardHost(); } catch (ArgumentException ex) when (ex.Message.Contains("loopback")) { logger.LogError(ex, "Fix ASPIRE_RESOURCE_SERVICE_ENDPOINT_URL to point at 127.0.0.1/localhost."); } Prevention
- Never point the dashboard's resource service URL at remote hosts
- Use port forwarding/tunnels to expose remote AppHosts on localhost
- Validate configured URLs in launchSettings before starting
When it happens
Trigger: Setting ResourceServiceEndpointUrl (environment/config) to a non-loopback host such as https://myhost.example.com or a LAN IP, then starting the dashboard service host.
Common situations: Container/remote-dev setups where developers point the dashboard at a remote AppHost; misconfigured port-forward URLs; copying config from a machine with a different hostname.
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
- Could not determine an appropriate location for local…
- Invalid operation specified. Valid operations are…
- A BlobServiceClient could not be configured. Ensure valid…
- A BlobServiceClient could not be configured. Ensure valid…
- A ChatCompletionsClient could not be configured. Ensure…
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/8e97085bc024e219.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting/Dashboard/DashboardServiceHost.cs:208
return new ResourceServiceEndpointInfo(ip, effectivePort, UseListenLocalhost: false, scheme);
}
else if (configuredUri.IsLoopback || IsLocalhostOrLocalhostTld(configuredUri))
{
// For "localhost" or *.localhost hosts, bind to both IPv4 and IPv6 loopback.
// Kestrel does not support ListenLocalhost with port 0, so fall back to
// binding on IPv4 loopback when a dynamic port is needed.
if (effectivePort == 0)
{
return new ResourceServiceEndpointInfo(IPAddress.Loopback, Port: 0, UseListenLocalhost: false, scheme);
}
else
{
return new ResourceServiceEndpointInfo(IPAddress.Loopback, effectivePort, UseListenLocalhost: true, scheme);
}
}
else
{
throw new ArgumentException($"{KnownConfigNames.ResourceServiceEndpointUrl} must contain a local loopback address.");
}
}
/// <summary>
/// Determines the scheme for the resource service endpoint. When a URI is explicitly
/// configured, its scheme is used. When no URI is provided, defaults to HTTPS unless
/// unsecured transport is explicitly allowed.
/// </summary>
internal static string ResolveScheme(Uri? configuredUri, bool allowUnsecuredTransport)
{
if (configuredUri is not null)
{
return configuredUri.Scheme;
}
return allowUnsecuredTransport ? "http" : "https";
}
View on GitHub (pinned to 25830f84bd)