microsoft/aspire · error · ArgumentException
Target endpoint ' ' on resource ' ' has already been added…
Error message
Target endpoint '{targetEndpoint.EndpointName}' on resource '{targetEndpoint.Resource.Name}' has already been added to dev tunnel '{tunnel.Name}'. What it means
AddDevTunnelPort prevents the same endpoint reference from being added twice to one dev tunnel. It checks the tunnel's existing Ports for a port whose TargetEndpoint equals the given reference and throws ArgumentException naming the 'targetEndpoint' parameter if found. Each endpoint on a resource can only map to one tunnel port per tunnel.
Solutions
- Remove the duplicate WithReference call that passes the same endpoint to the tunnel.
- If multiple ports are needed, expose distinct EndpointAnnotation endpoints on the target resource and reference each once.
- Check the tunnel builder chain for shared helper methods that may already have added the endpoint.
Example fix
// before
var tunnel = builder.AddDevTunnel("t")
.WithReference(api.GetEndpoint("https"))
.WithReference(api.GetEndpoint("https")); // duplicate
// after
var tunnel = builder.AddDevTunnel("t")
.WithReference(api.GetEndpoint("https")); Defensive patterns
Strategy: validation
Validate before calling
// ensure each endpoint is referenced at most once per tunnel
var seen = new HashSet<string>();
void AddRef(Aspire.Hosting.ApplicationModel.IResourceBuilder<DevTunnelResource> t, Aspire.Hosting.ApplicationModel.EndpointReference e)
{
if (!seen.Add($"{t.Resource.Name}:{e.EndpointName}:{e.Resource.Name}"))
throw new InvalidOperationException($"Endpoint {e.EndpointName} already added to tunnel {t.Resource.Name}");
} Prevention
- Keep tunnel wiring in one place; avoid multiple helper methods adding the same endpoint
- Search builder chains for duplicated WithReference calls on the same endpoint
- Prefer distinct named endpoints per tunneled service
When it happens
Trigger: Calling WithReference(tunnelBuilder, endpoint) — or chaining WithReference for the same endpoint — more than once against the same tunnel, e.g. WithReference(tunnel, api.GetEndpoint("https")) appearing twice, or an endpoint being routed through multiple WithReference calls.
Common situations: Copy-pasted builder chains adding the same endpoint twice; a shared extension method that also adds the endpoint to a tunnel the user already wired; accidentally passing the same EndpointReference instead of two different endpoints.
Related errors
- Cannot tunnel endpoint
- Cannot tunnel endpoint
- Connector operation ' ' is configured more than once.
- Unsupported provider. Supported providers are 'microsoft'…
- A ConfigureRadiusInfrastructure callback left container
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/ca350ec94d62e56a.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.DevTunnels/DevTunnelResourceBuilderExtensions.cs:578
}
}
});
return builder;
}
private static void AddDevTunnelPort(
IResourceBuilder<DevTunnelResource> tunnelBuilder,
EndpointReference targetEndpoint,
DevTunnelPortOptions? portOptions)
{
var tunnel = tunnelBuilder.Resource;
var targetResource = targetEndpoint.Resource;
if (tunnel.Ports.FirstOrDefault(p => p.TargetEndpoint == targetEndpoint) is { } existingPort)
{
// Port already added to the tunnel for this endpoint
throw new ArgumentException($"Target endpoint '{targetEndpoint.EndpointName}' on resource '{targetEndpoint.Resource.Name}' has already been added to dev tunnel '{tunnel.Name}'.", nameof(targetEndpoint));
}
if (targetEndpoint.Resource.Annotations.OfType<EndpointAnnotation>()
.SingleOrDefault(a => string.Equals(a.Name, targetEndpoint.EndpointName, StringComparisons.EndpointAnnotationName)) is { } targetEndpointAnnotation)
{
// The target endpoint already exists so let's ensure it's target is localhost
if (!EndpointHostHelpers.IsLocalhostOrLocalhostTld(targetEndpointAnnotation.TargetHost))
{
// Target endpoint is not localhost so can't be tunneled
throw new ArgumentException($"Cannot tunnel endpoint '{targetEndpointAnnotation.Name}' with host '{targetEndpointAnnotation.TargetHost}' on resource '{targetResource.Name}' because it is not a localhost endpoint.", nameof(targetEndpoint));
}
}
portOptions ??= new();
if (portOptions.Protocol is { } proto && proto is not "http" and not "https" and not "auto")
{
throw new ArgumentException($"Invalid protocol '{proto}' specified in port options. Supported protocols are 'http', 'https', or 'auto'. Set protocol to null to use the endpoint's scheme.", nameof(portOptions));
}View on GitHub (pinned to 25830f84bd)