{"record":{"id":"8934776fcceb5ad1","repo":"microsoft/aspire","slug":"external-service-must-have-either-a-uri-or-a-url-parameter","errorCode":null,"errorMessage":"External service must have either a URI or a URL parameter defined.","messagePattern":"External service must have either a URI or a URL parameter defined\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"critical","filePath":"src/Aspire.Hosting.Yarp/ConfigurationBuilder/YarpCluster.cs","lineNumber":170,"sourceCode":"            (false, true) => \"http\",\n            _ => throw new ArgumentException(\"Cannot find a http or https endpoint for this resource.\", nameof(resource))\n        };\n\n        return [$\"{scheme}://{resourceName}\"];\n    }\n\n    private static object GetAddressFromExternalService(ExternalServiceResource externalService)\n    {\n        if (externalService.Uri is not null)\n        {\n            return externalService.Uri.ToString();\n        }\n        if (externalService.UrlParameter is not null)\n        {\n            return externalService.UrlParameter;\n        }\n        // This shouldn't get to here as the ExternalServiceResource should ensure the URL is a valid absolute URI.\n        throw new InvalidOperationException(\"External service must have either a URI or a URL parameter defined.\");\n    }\n}\n\n/// <summary>\n/// Provides extension methods for configuring a YARP cluster.\n/// </summary>\npublic static class YarpClusterExtensions\n{\n    /// <summary>\n    /// Set the ForwarderRequestConfig for the cluster.\n    /// </summary>\n    /// <remarks>This overload is not available in polyglot app hosts. Use the DTO-based overload instead.</remarks>\n    [AspireExportIgnore(Reason = \"ForwarderRequestConfig is not ATS-compatible. Use the DTO-based overload instead.\")]\n    public static YarpCluster WithForwarderRequestConfig(this YarpCluster cluster, ForwarderRequestConfig config)\n    {\n        cluster.Configure(c => c with { HttpRequest = config });\n        return cluster;\n    }","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.Yarp/ConfigurationBuilder/YarpCluster.cs#L152-L188","documentation":"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.","triggerScenarios":"Calling ResolveTargets against an ExternalServiceResource whose Uri is null and whose UrlParameter is null, so GetAddressFromExternalService falls past both lookups and throws InvalidOperationException.","commonSituations":"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.","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)."],"exampleFix":"// before\nvar api = builder.AddExternalService(\"api\");\n// after\nvar api = builder.AddExternalService(\"api\", \"https://api.example.com\");","handlingStrategy":"validation","validationCode":"if (externalService.UrlParameter is null && externalService.Uri is null)\n{\n    throw new InvalidOperationException($\"External service '{externalService.Name}' has no URI or URL parameter configured.\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["yarp","external-service","missing-url","configuration"],"backgroundTag":"missing-required-config-field","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"}