dotnet/orleans · critical · InvalidOperationException

WEBSITE_PRIVATE_PORTS must contain at least one TCP port.

Error message

WEBSITE_PRIVATE_PORTS must contain at least one TCP port.

What it means

An InvalidOperationException thrown by the Azure App Service silo host when the WEBSITE_PRIVATE_PORTS setting is missing or its first comma-separated value cannot be parsed as a TCP port. Azure App Service injects WEBSITE_PRIVATE_PORTS to tell the silo which private ports to bind; the code parses the first as the silo port with NumberStyles.None (unsigned integer). If parsing fails or the array is empty, startup aborts.

Source

Thrown at samples/Deployment/AzureAppService/Silo/Program.cs:109

app.MapBlazorHub();
app.MapFallbackToPage("/_Host");

await app.RunAsync();

static void ConfigureProductionOrleans(WebApplicationBuilder builder)
{
    var clusterId = GetRequiredSetting(builder, "ORLEANS_CLUSTER_ID");
    var serviceId = GetRequiredSetting(builder, "ORLEANS_SERVICE_ID");
    var storageUri = new Uri(GetRequiredSetting(builder, "ORLEANS_AZURE_STORAGE_URI"));
    var managedIdentityClientId = GetRequiredSetting(builder, "AZURE_CLIENT_ID");
    var privateIp = IPAddress.Parse(GetRequiredSetting(builder, "WEBSITE_PRIVATE_IP"));
    var privatePorts = GetRequiredSetting(builder, "WEBSITE_PRIVATE_PORTS")
        .Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);

    if (privatePorts.Length < 1
        || !int.TryParse(privatePorts[0], NumberStyles.None, CultureInfo.InvariantCulture, out var siloPort))
    {
        throw new InvalidOperationException(
            "WEBSITE_PRIVATE_PORTS must contain at least one TCP port.");
    }

    var credential = new DefaultAzureCredential(new DefaultAzureCredentialOptions
    {
        ManagedIdentityClientId = managedIdentityClientId,
    });
    var tableServiceClient = new TableServiceClient(storageUri, credential);

    builder.UseOrleans(siloBuilder =>
    {
        siloBuilder
            .Configure<SiloOptions>(options =>
            {
                options.SiloName = builder.Configuration["WEBSITE_INSTANCE_ID"]
                    ?? Environment.MachineName;
            })
            .Configure<ClusterOptions>(options =>

View on GitHub (pinned to fca799fa70)

Solutions

  1. Deploy/run the silo inside an Azure App Service so the platform injects WEBSITE_PRIVATE_PORTS automatically.
  2. If running locally, set WEBSITE_PRIVATE_PORTS to a valid port (e.g., '11111') in environment/launchSettings for testing.
  3. Verify the value has no stray characters/signs — NumberStyles.None rejects '+','-', whitespace, and hex.

Example fix

// before
if (privatePorts.Length < 1
    || !int.TryParse(privatePorts[0], NumberStyles.None, CultureInfo.InvariantCulture, out var siloPort))
{
    throw new InvalidOperationException("WEBSITE_PRIVATE_PORTS must contain at least one TCP port.");
}

// after (explicit, actionable error)
if (privatePorts.Length < 1)
    throw new InvalidOperationException("WEBSITE_PRIVATE_PORTS is empty; configure at least one private TCP port in the App Service.");
if (!int.TryParse(privatePorts[0], NumberStyles.None, CultureInfo.InvariantCulture, out var siloPort))
    throw new InvalidOperationException($"WEBSITE_PRIVATE_PORTS[0] = '{privatePorts[0]}' is not a valid TCP port.");
Defensive patterns

Strategy: validation

Validate before calling

var raw = builder.Configuration["WEBSITE_PRIVATE_PORTS"];
var ports = raw?.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
if (ports is null || ports.Length == 0 || !int.TryParse(ports[0], NumberStyles.None, CultureInfo.InvariantCulture, out _))
    throw new InvalidOperationException("WEBSITE_PRIVATE_PORTS must contain at least one TCP port.");

Prevention

When it happens

Trigger: Silo startup in an Azure App Service where WEBSITE_PRIVATE_PORTS is unset, empty, or contains a non-numeric/signed value in position 0. The Split + int.TryParse(NumberStyles.None) guard catches both 'no ports' and 'unparseable port'.

Common situations: Running the sample outside Azure App Service (the env var is never set). A corrupted/misconfigured app setting. The App Service plan variant not injecting the variable as expected.

Related errors


AI-assisted analysis of dotnet/orleans@fca799fa70 (2026-08-13). Data as JSON: /api/errors/65838bbdc8b3c868. Report an issue: GitHub.