microsoft/aspire · error · InvalidOperationException
Endpoint ' ' must specify a port for scheme ' '.
Error message
Endpoint '{endpoint.Name}' must specify a port for scheme '{scheme}'. What it means
GetDefaultPort supplies conventional ports for http (80) and https (443) when an endpoint has no explicit port. For any other scheme it cannot infer a default, so it throws InvalidOperationException telling the developer the endpoint must specify a port explicitly via WithEndpoint/EndpointAnnotation.
Solutions
- Specify the port explicitly: builder.AddXyz("name").WithEndpoint(scheme: "tcp", port: 5672, targetPort: 5672).
- Use the standard 'http'/'https' schemes when default ports (80/443) are what you want.
- Fix the scheme name if it was a typo of http/https.
- Catch InvalidOperationException during manifest generation to report which endpoint/scheme needs a port.
Example fix
// before .WithEndpoint(scheme: "grpc") // no port -> throws on property evaluation // after .WithEndpoint(scheme: "grpc", port: 5001, targetPort: 5001)
Defensive patterns
Strategy: validation
Validate before calling
// before evaluating endpoint properties
static bool HasResolvablePort(EndpointAnnotation e) =>
e.TargetPort is int || e.Port is int ||
string.Equals(e.Scheme, "http", StringComparison.OrdinalIgnoreCase) ||
string.Equals(e.Scheme, "https", StringComparison.OrdinalIgnoreCase); Try / catch
try
{
var expr = env.GetEndpointPropertyExpression(endpoint, EndpointProperty.HostAndPort);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("must specify a port"))
{
// instruct user to call WithEndpoint(port: ...) for non-http(s) schemes
} Prevention
- Always pass port (and targetPort) when using custom schemes like tcp/grpc/amqp.
- Reserve http/https schemes for endpoints relying on default ports 80/443.
- Check endpoint.Scheme in custom resources before assuming a default port exists.
- Catch this at manifest generation and emit a clear 'endpoint X needs a port' diagnostic.
When it happens
Trigger: Evaluating an endpoint property (host:port expression, manifest generation) for an endpoint whose Scheme is neither http nor https and whose TargetPort/Port is null.
Common situations: Custom schemes like 'tcp', 'grpc', or 'amqp' registered with WithEndpoint but without a port; endpoints declared for port-forwarding where the container exposes no fixed port; typo'd scheme names ('https ' or 'HTTPs2').
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- The property ' ' is not supported for the endpoint ' '.
- AllocatedEndpoint must use the same network as the…
- The default AllocatedEndpoint's network ID must match the…
- Anonymous volumes cannot be read-only.
- Bind mounts must specify a source path.
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/d4b0938fc6efdc1f.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting/ApplicationModel/IComputeEnvironmentResource.cs:80
EndpointProperty.HostAndPort => ReferenceExpression.Create($"{host.Value}:{port.ToString(CultureInfo.InvariantCulture)}"),
EndpointProperty.TlsEnabled => ReferenceExpression.Create($"{(endpoint.TlsEnabled ? bool.TrueString : bool.FalseString)}"),
_ => throw new InvalidOperationException($"The property '{property}' is not supported for the endpoint '{endpoint.Name}'.")
};
}
private static int GetDefaultPort(string scheme, EndpointAnnotation endpoint)
{
if (string.Equals(scheme, "http", StringComparison.OrdinalIgnoreCase))
{
return 80;
}
if (string.Equals(scheme, "https", StringComparison.OrdinalIgnoreCase))
{
return 443;
}
throw new InvalidOperationException($"Endpoint '{endpoint.Name}' must specify a port for scheme '{scheme}'.");
}
private static bool IsDefaultPort(string scheme, int port)
{
return string.Equals(scheme, "http", StringComparison.OrdinalIgnoreCase) && port == 80 ||
string.Equals(scheme, "https", StringComparison.OrdinalIgnoreCase) && port == 443;
}
}
View on GitHub (pinned to 25830f84bd)