microsoft/aspire · error · ArgumentException
Invalid protocol ' ' specified in port options. Supported…
Error message
Invalid protocol '{proto}' specified in port options. Supported protocols are 'http', 'https', or 'auto'. Set protocol to null to use the endpoint's scheme. What it means
When portOptions.Protocol is explicitly supplied to AddDevTunnelPort it must be 'http', 'https', or 'auto'; anything else throws ArgumentException naming portOptions. Passing null is allowed and means 'infer from the endpoint scheme'. Dev tunnels need a valid protocol to declare for the forwarded port.
Solutions
- Set portOptions.Protocol to one of 'http', 'https', or 'auto' (exact lowercase spelling).
- Leave Protocol null so it defaults from the endpoint's scheme.
- Use 'auto' when you want the tunnel to negotiate the protocol.
Example fix
// before
builder.AddDevTunnel("t").WithReference(api.GetEndpoint("https"), p => p.Protocol = "tcp");
// after
builder.AddDevTunnel("t").WithReference(api.GetEndpoint("https"), p => p.Protocol = "https"); Defensive patterns
Strategy: validation
Validate before calling
// validate protocol before building
var allowed = new[] { "http", "https", "auto" };
if (portOptions.Protocol is { } p && !allowed.Contains(p))
throw new ArgumentException($"Protocol '{p}' invalid; use http/https/auto or null"); Prevention
- Use string constants instead of hand-typed literals for Protocol
- Prefer leaving Protocol null to inherit the endpoint scheme
- Remember matching is exact lowercase
When it happens
Trigger: Calling AddDevTunnelPort/WithReference tunnel configuration with PortOptions such as p => p.Protocol = "tcp" or a typo like "HTTP"/"htps" — any value outside http/https/auto.
Common situations: Copy-pasting protocol values intended for Docker or Kestrel configs ('tcp', 'Http'); typos; assuming case-insensitivity that the check does not perform.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Cannot tunnel endpoint
- {result.ValidationMessage}
- The label ' ' is invalid. A valid label must: - consist of…
- The tunnel ID ' ' is invalid. A valid tunnel ID must: -…
- -32602
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/80569c3f542eb4a7.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.DevTunnels/DevTunnelResourceBuilderExtensions.cs:595
// 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));
}
portOptions.Protocol ??= targetEndpoint.Scheme switch
{
"https" or "http" => targetEndpoint.Scheme,
_ => throw new ArgumentException($"Cannot tunnel endpoint '{targetEndpoint.EndpointName}' on resource '{targetResource.Name}' because it uses the unsupported scheme '{targetEndpoint.Scheme}'. Only 'http' and 'https' endpoints can be tunneled."),
};
portOptions.Description ??= $"{targetResource.Name}/{targetEndpoint.EndpointName}";
var portName = $"{tunnel.Name}-{targetResource.Name}-{targetEndpoint.EndpointName}";
portOptions.Labels ??= [];
portOptions.Labels.Add(targetResource.Name);
portOptions.Labels.Add(targetEndpoint.EndpointName);
if (!TryValidateLabels(portOptions.Labels, out var errorMessage))
{
throw new ArgumentException(errorMessage, nameof(portOptions));
}
View on GitHub (pinned to 25830f84bd)