microsoft/aspire · critical · InvalidOperationException
External service must have either a URI or a URL parameter…
Error message
External service must have either a URI or a URL parameter defined.
What it means
Thrown by YarpCluster.GetAddressFromExternalService when an ExternalServiceResource has neither a resolved URI nor a URL parameter. The library requires external services used as YARP cluster destinations to resolve to an absolute address so the reverse proxy knows where to forward requests. The comment notes the ExternalServiceResource should normally guarantee a valid absolute URI, so this usually indicates the resource was configured without any URL information.
Solutions
- Set the external service URI explicitly, e.g. builder.AddExternalService("api", "https://api.example.com").
- If the URL is dynamic, pass a parameter via the URL-parameter overload so externalService.UrlParameter is populated.
- Verify the resource producing the URL parameter resolves at runtime (check the parameter's value/env var is not null).
Example fix
// before
var api = builder.AddExternalService("api");
// after
var api = builder.AddExternalService("api", "https://api.example.com"); Defensive patterns
Strategy: validation
Validate before calling
if (externalService.UrlParameter is null && externalService.Uri is null)
{
throw new InvalidOperationException($"External service '{externalService.Name}' has no URI or URL parameter configured.");
} Prevention
- Always create external services with an explicit URL or a URL parameter overload.
- Keep parameter values in appsettings/env so UrlParameter resolves at runtime.
- Add a startup check that all external services referenced by YARP clusters resolve to an absolute URI.
When it happens
Trigger: Calling ResolveTargets against an ExternalServiceResource whose Uri is null and whose UrlParameter is null, so GetAddressFromExternalService falls past both lookups and throws InvalidOperationException.
Common situations: Declaring builder.AddExternalService(name) without a URI; removing or renaming the environment variable / parameter that supplies the URL at runtime; constructing an external service resource manually in code without calling the URL-providing overloads.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- At least one gateway endpoint (HTTP or HTTPS) must be…
- Configuring programmatically clusters while providing a…
- Configuring programmatically routes while providing a…
- Providing a configuration file isn't supported when…
- The value ' ' is not a valid HTTP version. Expected format…
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/8934776fcceb5ad1.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.Yarp/ConfigurationBuilder/YarpCluster.cs:170
(false, true) => "http",
_ => throw new ArgumentException("Cannot find a http or https endpoint for this resource.", nameof(resource))
};
return [$"{scheme}://{resourceName}"];
}
private static object GetAddressFromExternalService(ExternalServiceResource externalService)
{
if (externalService.Uri is not null)
{
return externalService.Uri.ToString();
}
if (externalService.UrlParameter is not null)
{
return externalService.UrlParameter;
}
// This shouldn't get to here as the ExternalServiceResource should ensure the URL is a valid absolute URI.
throw new InvalidOperationException("External service must have either a URI or a URL parameter defined.");
}
}
/// <summary>
/// Provides extension methods for configuring a YARP cluster.
/// </summary>
public static class YarpClusterExtensions
{
/// <summary>
/// Set the ForwarderRequestConfig for the cluster.
/// </summary>
/// <remarks>This overload is not available in polyglot app hosts. Use the DTO-based overload instead.</remarks>
[AspireExportIgnore(Reason = "ForwarderRequestConfig is not ATS-compatible. Use the DTO-based overload instead.")]
public static YarpCluster WithForwarderRequestConfig(this YarpCluster cluster, ForwarderRequestConfig config)
{
cluster.Configure(c => c with { HttpRequest = config });
return cluster;
}View on GitHub (pinned to 25830f84bd)