dotnet/orleans · error · InvalidOperationException

AZURE_CLIENT_ID must contain the user-assigned managed ident

Error message

AZURE_CLIENT_ID must contain the user-assigned managed identity client ID.

What it means

An InvalidOperationException thrown by AzureTableServiceClientFactory.Create when AzureTable:ServiceUri is a valid HTTPS URI but AZURE_CLIENT_ID does not parse as a GUID. The factory builds a DefaultAzureCredential with ManagedIdentityClientId, which must be the client ID (a Guid) of a user-assigned managed identity; a non-GUID value would produce a credential that cannot resolve the identity.

Source

Thrown at samples/Deployment/AzureContainerApps/Infrastructure/AzureTableServiceClientFactory.cs:26

public static class AzureTableServiceClientFactory
{
    public static TableServiceClient Create(IConfiguration configuration, IHostEnvironment environment)
    {
        var serviceUriValue = configuration["AzureTable:ServiceUri"];
        if (!string.IsNullOrWhiteSpace(serviceUriValue))
        {
            if (!Uri.TryCreate(serviceUriValue, UriKind.Absolute, out var serviceUri)
                || serviceUri.Scheme != Uri.UriSchemeHttps)
            {
                throw new InvalidOperationException(
                    "AzureTable:ServiceUri must be an absolute HTTPS Azure Table service URI.");
            }

            var credentialOptions = new DefaultAzureCredentialOptions();
            var managedIdentityClientId = GetRequiredValue(configuration, "AZURE_CLIENT_ID");
            if (!Guid.TryParse(managedIdentityClientId, out _))
            {
                throw new InvalidOperationException(
                    "AZURE_CLIENT_ID must contain the user-assigned managed identity client ID.");
            }

            credentialOptions.ManagedIdentityClientId = managedIdentityClientId;
            return new TableServiceClient(serviceUri, new DefaultAzureCredential(credentialOptions));
        }

        var connectionString = configuration["AzureTable:ConnectionString"];
        if (environment.IsDevelopment()
            && string.Equals(connectionString, "UseDevelopmentStorage=true", StringComparison.OrdinalIgnoreCase))
        {
            return new TableServiceClient(connectionString);
        }

        throw new InvalidOperationException(
            "Configure AzureTable:ServiceUri for Azure, or use Azurite with "
            + "AzureTable:ConnectionString=UseDevelopmentStorage=true in Development.");
    }

View on GitHub (pinned to fca799fa70)

Solutions

  1. Set AZURE_CLIENT_ID to the user-assigned managed identity's client ID (a GUID) found in the identity's Azure portal properties.
  2. Confirm you are using the 'Client ID' (appId), not the 'Object ID' or 'Principal ID'.
  3. If using a system-assigned identity instead, remove ServiceUri handling or refactor the factory to omit ManagedIdentityClientId.

Example fix

// before (env)
AZURE_CLIENT_ID=my-storage-account

// after
AZURE_CLIENT_ID=12345678-1234-1234-1234-1234567890ab
Defensive patterns

Strategy: validation

Validate before calling

var clientId = configuration["AZURE_CLIENT_ID"];
if (!Guid.TryParse(clientId, out _))
    throw new InvalidOperationException("AZURE_CLIENT_ID must be a GUID (user-assigned managed identity client ID).");

Prevention

When it happens

Trigger: The HTTPS service URI path is taken, but AZURE_CLIENT_ID is missing, an object ID (not a client ID), an application URI, or a mistyped string. Guid.TryParse returns false.

Common situations: Confusing the managed identity's object/principal ID with its client ID. Copying the tenant ID. The env var unset in the container app but ServiceUri set, so GetRequiredValue already caught empty — here the value is present but malformed.

Related errors


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