microsoft/aspire · error · InvalidOperationException

The Azure parameter ' ' must be supplied when ' ' is…

Error message

The Azure parameter '{AzureBicepResource.KnownParameters.PrincipalType}' must be supplied when '{AzureBicepResource.KnownParameters.UserPrincipalId}' is provided explicitly.

What it means

A UserPrincipalId parameter was supplied explicitly (not auto-populated by Aspire) but PrincipalType was not. Bicep role assignments need both the principal id and its type (User/ServicePrincipal/Group), so the provisioner throws rather than guessing.

Solutions

  1. Also set resource.Params[AzureBicepResource.KnownParameters.PrincipalType] (e.g. "User") whenever you set UserPrincipalId.
  2. Remove the explicit UserPrincipalId and let Aspire bind the deployment principal automatically.
  3. Load both values from configuration together so they stay in sync.
  4. Prefer AddAzureContainerAppEnvironment which populates principal parameters for you.

Example fix

// before
resource.Params[AzureBicepResource.KnownParameters.UserPrincipalId] = userId;
// after
resource.Params[AzureBicepResource.KnownParameters.UserPrincipalId] = userId;
resource.Params[AzureBicepResource.KnownParameters.PrincipalType] = "User";
Defensive patterns

Strategy: validation

Validate before calling

bool hasUpid = resource.Parameters.TryGetValue(AzureBicepResource.KnownParameters.UserPrincipalId, out var upid) && upid is not null;
bool hasType = resource.Parameters.TryGetValue(AzureBicepResource.KnownParameters.PrincipalType, out var ptype) && ptype is not null;
if (hasUpid && !hasType) throw new InvalidOperationException("PrincipalType must accompany UserPrincipalId.");

Try / catch

try { await provisioner.ProvisionAsync(...); } catch (InvalidOperationException ex) when (ex.Message.Contains("PrincipalType")) { logger.LogError(ex, "Set KnownParameters.PrincipalType alongside UserPrincipalId"); throw; }

Prevention

When it happens

Trigger: Setting resource.Params[AzureBicepResource.KnownParameters.UserPrincipalId] manually (e.g. from config) while leaving KnownParameters.PrincipalType unset, and PrincipalType is present-but-null in Parameters.

Common situations: Hardcoding a user principal id for local testing; copying parameter setup that only set the id; the type parameter declared in the module but never assigned.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at src/Aspire.Hosting.Azure/Provisioning/Provisioners/BicepProvisioner.cs:1420

            // Published artifacts bind this deployment-principal parameter from the outer
            // main.bicep template. Direct `aspire deploy` has no outer template, so use the
            // authenticated principal that performs the data-plane deployment.
            resource.Parameters[AzureBicepResource.KnownParameters.UserPrincipalId] = context.Principal.Id;
            populatedUserPrincipalId = true;
        }

        if (resource.Parameters.TryGetValue(AzureBicepResource.KnownParameters.PrincipalName, out var principalName) && principalName is null)
        {
            ValidateUnknownPrincipalParameter(context);

            resource.Parameters[AzureBicepResource.KnownParameters.PrincipalName] = context.Principal.Name;
        }

        if (resource.Parameters.TryGetValue(AzureBicepResource.KnownParameters.PrincipalType, out var principalType) && principalType is null)
        {
            if (hasUserPrincipalId && !populatedUserPrincipalId)
            {
                throw new InvalidOperationException(
                    $"The Azure parameter '{AzureBicepResource.KnownParameters.PrincipalType}' must be supplied when " +
                    $"'{AzureBicepResource.KnownParameters.UserPrincipalId}' is provided explicitly.");
            }

            if (!hasUserPrincipalId)
            {
                ValidateUnknownPrincipalParameter(context);
            }

            // Use the principal type detected from the credential's access token (the `idtyp`
            // claim) instead of hardcoding "User". A hardcoded "User" caused the role-assignment
            // `-roles` deployments synthesized by AzureResourcePreparer to fail with
            // `UnmatchedPrincipalType` / `PrincipalNotFound` whenever the AppHost ran under a
            // service-principal / federated-workload-identity credential (CI, CD, deploy bots).
            // See https://github.com/microsoft/aspire/issues/13933.
            resource.Parameters[AzureBicepResource.KnownParameters.PrincipalType] = context.Principal.Type;
        }

View on GitHub (pinned to 25830f84bd)