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

  1. Make port and targetPort the same value on every isProxied: false endpoint.
  2. If you need different external/internal ports, keep the endpoint proxied (default) so the DCP proxy maps them.
  3. Update the app to listen on the exact port you expose and remove the mismatched Port override.
  4. 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

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


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)