microsoft/aspire · error · InvalidOperationException

Could not find tenant id

Error message

Could not find tenant id {subscriptionResource.TenantId} for subscription {subscriptionResource.DisplayName}.

What it means

During Azure provisioning, Aspire resolves the default subscription and its tenant by enumerating the tenants visible to the logged-in credential and matching the subscription's TenantId. This error means no tenant in that enumeration matched the subscription's tenant id, so the (subscription, tenant) pair cannot be returned. It is thrown as an InvalidOperationException because the ARM account state is inconsistent with the subscription lookup.

Solutions

  1. Run `az login` (or re-authenticate the credential) ensuring the account is a member of the tenant that owns the target subscription.
  2. Run `az account list` / `az account set --subscription <id>` to make the intended subscription the default and confirm its tenantId matches your login tenant.
  3. If using a service principal, grant it a role in the owning tenant and ensure it authenticates against that tenant (AZURE_TENANT_ID set correctly).
  4. Verify no tenant filters or ARM client options restrict GetTenants() results; retry after clearing cached Azure CLI tokens (`az account clear` then `az login`).

Example fix

// before
az login --tenant 11111111-1111-1111-1111-111111111111  // tenant that does not own the subscription
// after
az login --tenant 22222222-2222-2222-2222-222222222222  // tenant owning the subscription
az account set --subscription 33333333-3333-3333-3333-333333333333
Defensive patterns

Strategy: validation

Validate before calling

var sub = await armClient.GetDefaultSubscriptionAsync(ct);
var tenantVisible = false;
await foreach (var t in armClient.GetTenants().GetAllAsync(cancellationToken: ct))
    if (t.Data.TenantId == sub.Data.TenantId) { tenantVisible = true; break; }
if (!tenantVisible)
    throw new InvalidOperationException($"Login tenant does not own subscription '{sub.Data.DisplayName}'; re-authenticate with 'az login --tenant <tenantId>'.");

Type guard

bool TenantMatchesSubscription(string? subscriptionTenantId, IEnumerable<string> visibleTenantIds) =>
    subscriptionTenantId is not null && visibleTenantIds.Contains(subscriptionTenantId, StringComparer.OrdinalIgnoreCase);

Try / catch

try
{
    var (subscription, tenant) = await client.GetSubscriptionAndTenantAsync(ct);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("Could not find tenant id"))
{
    // re-authenticate against the subscription's owning tenant, then retry
}

Prevention

When it happens

Trigger: Calling GetSubscriptionAndTenantAsync when the credential can list tenants but none has TenantId equal to the default subscription's TenantId — e.g. the subscription belongs to a tenant the principal is not a member of, the tenant listing was filtered/partial, or the default subscription resolved to an unexpected entry (stale Azure CLI account cache, guest access, cross-tenant subscription).

Common situations: Developers hit this after switching az accounts with `az login` while a different subscription is default, when using a service principal with access to a subscription in another tenant but no membership there, when tenant-level permissions block listing the tenant resource, or after subscription moves between tenants.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16). Data as JSON: /api/errors/710f906ae964cc8f. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Hosting.Azure/Provisioning/Internal/DefaultArmClientProvider.cs:79

        public async Task<(ISubscriptionResource subscription, ITenantResource tenant)> GetSubscriptionAndTenantAsync(CancellationToken cancellationToken = default)
        {
            var subscription = await armClient.GetDefaultSubscriptionAsync(cancellationToken).ConfigureAwait(false);
            var subscriptionResource = new DefaultSubscriptionResource(subscription);

            ITenantResource? tenantResource = null;

            await foreach (var tenant in armClient.GetTenants().GetAllAsync(cancellationToken: cancellationToken).ConfigureAwait(false))
            {
                if (tenant.Data.TenantId == subscriptionResource.TenantId)
                {
                    tenantResource = new DefaultTenantResource(tenant);
                    break;
                }
            }

            if (tenantResource is null)
            {
                throw new InvalidOperationException($"Could not find tenant id {subscriptionResource.TenantId} for subscription {subscriptionResource.DisplayName}.");
            }

            return (subscriptionResource, tenantResource);
        }

        public async Task<IEnumerable<ITenantResource>> GetAvailableTenantsAsync(CancellationToken cancellationToken = default)
        {
            var tenants = new List<ITenantResource>();

            await foreach (var tenant in armClient.GetTenants().GetAllAsync(cancellationToken: cancellationToken).ConfigureAwait(false))
            {
                tenants.Add(new DefaultTenantResource(tenant));
            }

            return tenants;
        }

        public async Task<IEnumerable<ISubscriptionResource>> GetAvailableSubscriptionsAsync(CancellationToken cancellationToken = default)

View on GitHub (pinned to 25830f84bd)