microsoft/aspire · error · InvalidOperationException
The endpoint ' ' for resource ' ' is not using a proxy, and…
Error message
The endpoint '{endpoint.Name}' for resource '{modelResourceName}' is not using a proxy, and it has a value of Port property that is different from the value of TargetPort property. For proxy-less endpoints they must match. What it means
For proxy-less (unproxied) endpoints, DcpModelUtilities requires the Port (the publicly exposed port) and TargetPort (the port the process listens on) to be identical, because without the DCP proxy there is no port forwarding between them. When they differ, endpoint allocation cannot produce a coherent mapping and it throws InvalidOperationException.
Solutions
- Make port and targetPort the same value on every isProxied: false endpoint.
- If you need different external/internal ports, keep the endpoint proxied (default) so the DCP proxy maps them.
- Update the app to listen on the exact port you expose and remove the mismatched Port override.
- For containers with proxy-less endpoints, also ensure the container internally listens on that same port.
Example fix
// before: mismatched ports on proxy-less endpoint .WithEndpoint(port: 8080, targetPort: 5000, isProxied: false) // after: equal ports for proxy-less endpoints .WithEndpoint(port: 8080, targetPort: 8080, isProxied: false)
Defensive patterns
Strategy: validation
Validate before calling
static void EnsureProxylessPortsMatch(EndpointAnnotation e)
{
if (!e.IsProxied && e.Port is int p && p != e.TargetPort)
throw new InvalidOperationException($"Proxy-less endpoint '{e.Name}' requires Port == TargetPort.");
} Type guard
static bool IsProxylessConfigValid(EndpointAnnotation e) =>
e.IsProxied || e.Port is not int p || p == e.TargetPort; Try / catch
try { await builder.Build().RunAsync(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("For proxy-less endpoints they must match"))
{
// equalize port and targetPort or re-enable the proxy
} Prevention
- Keep port == targetPort for every isProxied: false endpoint
- Use the proxy (default) when you need different external/internal ports
- Configure the app to listen exactly on the exposed port in proxy-less mode
When it happens
Trigger: Calling WithEndpoint with an explicit port and targetPort that differ while passing isProxied: false (or using a resource where proxying is disabled), then running the AppHost — e.g. WithEndpoint(port: 8080, targetPort: 5000, isProxied: false).
Common situations: Migrating from proxied to proxy-less endpoints (e.g. for gRPC/HTTPS direct binding) without consolidating port values; setting Port for a 'nice' external port while the app still listens on a different port; forgetting that proxy-less mode removes the port-mapping layer entirely.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- The endpoint ' ' for container resource ' ' must specify…
- At least one gateway endpoint (HTTP or HTTPS) must be…
- AzureSandboxOptions.AutoDeleteEnabled must be set when…
- AzureSandboxOptions.AutoSuspendEnabled must be set when…
- Could not create HTTP command for resource
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/2c7a9a5a768611af.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting/Dcp/DcpModelUtilities.cs:44
return start == false &&
modelResource.TryGetLastAnnotation<ExplicitStartupAnnotation>(out _) &&
modelResource.GetLifetimeType() != Lifetime.Persistent;
}
internal static void ValidateEndpointPorts(IResource modelResource, EndpointAnnotation endpoint)
{
var modelResourceName = modelResource.Name ?? "(unknown)";
if (modelResource.IsContainer())
{
if (EndpointAnnotation.NormalizePort(endpoint.TargetPort) is null)
{
throw new InvalidOperationException($"The endpoint '{endpoint.Name}' for container resource '{modelResourceName}' must specify the {nameof(EndpointAnnotation.TargetPort)} value");
}
}
else if (!endpoint.IsProxied && endpoint.Port is int && endpoint.Port != endpoint.TargetPort)
{
throw new InvalidOperationException($"The endpoint '{endpoint.Name}' for resource '{modelResourceName}' is not using a proxy, and it has a value of {nameof(EndpointAnnotation.Port)} property that is different from the value of {nameof(EndpointAnnotation.TargetPort)} property. For proxy-less endpoints they must match.");
}
}
/// <summary>
/// Examines the Aspire resource annotations and adds equivalent ServiceProducerAnnotations to the corresponding DCP resource.
/// </summary>
internal static void AddServicesProducedInfo<TDcpResource>(
RenderedModelResource<TDcpResource> appResource,
IEnumerable<IAppResource> appResources)
where TDcpResource : CustomResource, IKubernetesStaticMetadata
{
var modelResource = appResource.ModelResource;
var modelResourceName = modelResource.Name ?? "(unknown)";
var servicesProduced = appResources.OfType<ServiceWithModelResource>().Where(r => r.ModelResource == modelResource);
foreach (var sp in servicesProduced)
{
var ea = sp.EndpointAnnotation;View on GitHub (pinned to 25830f84bd)