hashicorp/terraform · error

unable to build authorizer for Resource Manager API: %+v

Error message

unable to build authorizer for Resource Manager API: %+v

What it means

Thrown by Azure buildClient when ARM-scope authentication is required (either because no direct auth method was supplied, so Terraform falls back to listing the access key via ARM, or because lookup_blob_endpoint=true) and auth.NewAuthorizerFromCredentials for the ResourceManager scope fails. The %+v expands the real auth error.

Solutions

  1. Inspect the wrapped auth error for the specific missing or invalid credential field.
  2. Provide a complete service principal (client_id, client_secret or cert or OIDC, tenant_id, subscription_id) usable against ARM.
  3. If you intend Azure CLI auth, run `az login --subscription <id>` in the same shell and ensure the AZURE_* env vars do not override it incorrectly.
  4. Avoid needing ARM entirely by supplying an access_key or sas_token directly (then lookup_blob_endpoint stays false).
  5. For custom clouds, ensure environment metadata exposes a ResourceManager endpoint URL.

Example fix

# before: no creds + lookup_blob_endpoint=true forces ARM auth that fails
export ARM_LOOKUP_BLOB_ENDPOINT=true
# after: either supply ARM creds, or disable lookup and supply endpoint/access_key
export ARM_CLIENT_ID=...; export ARM_CLIENT_SECRET=...
export ARM_TENANT_ID=...; export ARM_SUBSCRIPTION_ID=...
export ARM_LOOKUP_BLOB_ENDPOINT=true
Defensive patterns

Strategy: validation

Validate before calling

func needsARM(c BackendConfig) bool {
    return c.AccessKey == "" && c.SasToken == "" && !c.UseAzureADAuthentication || c.LookupBlobEndpoint
}
// If needsARM(cfg) is true, ensure full SP creds or Azure CLI auth is available.

Type guard

null

Try / catch

client, err := azure.NewClient(ctx, cfg)
if err != nil && strings.Contains(err.Error(), "unable to build authorizer for Resource Manager API") {
    // distinguish: missing creds vs wrong cloud vs CLI not logged in — all surface in the wrapped err
}

Prevention

When it happens

Trigger: armAuthRequired is true (default branch of the auth switch, or LookupBlobEndpoint set) and auth.NewAuthorizerFromCredentials(ctx, *config.AuthConfig, config.AuthConfig.Environment.ResourceManager) returns err. Root causes mirror error 134 but against the ARM scope: bad SP credentials, missing fields, unsupported environment, or Azure CLI not available for CLI-based auth.

Common situations: Relying on the 'list access key via ARM' default without providing valid ARM creds; setting lookup_blob_endpoint=true but only providing SAS/access-key creds; CLI auth expected but `az login` not run in the current context; wrong cloud metadata for ResourceManager endpoint.

Related errors


AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11). Data as JSON: /api/errors/ada27da49276adcf. Report an issue: GitHub.

Appendix: source

Thrown at internal/backend/remote-state/azure/api_client.go:79

		var err error
		client.azureAdStorageAuth, err = auth.NewAuthorizerFromCredentials(ctx, *config.AuthConfig, config.AuthConfig.Environment.Storage)
		if err != nil {
			return nil, fmt.Errorf("unable to build authorizer for Storage API: %+v", err)
		}
	default:
		// AAD authentication (ARM scope) is required only when no auth method is specified, which falls back to listing the access key via ARM API.
		armAuthRequired = true
	}

	// If `config.LookupBlobEndpoint` is true, we need to authenticate with ARM to lookup the blob endpoint
	if config.LookupBlobEndpoint {
		armAuthRequired = true
	}

	if armAuthRequired {
		resourceManagerAuth, err := auth.NewAuthorizerFromCredentials(ctx, *config.AuthConfig, config.AuthConfig.Environment.ResourceManager)
		if err != nil {
			return nil, fmt.Errorf("unable to build authorizer for Resource Manager API: %+v", err)
		}

		// When using Azure CLI to auth, the user can leave the "subscription_id" unspecified. In this case the subscription id is inferred from
		// the Azure CLI default subscription.
		if config.SubscriptionID == "" {
			if cachedAuth, ok := resourceManagerAuth.(*auth.CachedAuthorizer); ok {
				if cliAuth, ok := cachedAuth.Source.(*auth.AzureCliAuthorizer); ok && cliAuth.DefaultSubscriptionID != "" {
					config.SubscriptionID = cliAuth.DefaultSubscriptionID
				}
			}
		}
		if config.SubscriptionID == "" {
			return nil, fmt.Errorf("subscription id not specified")
		}

		// Setup the SA client.
		client.storageAccountsClient, err = storageaccounts.NewStorageAccountsClientWithBaseURI(config.AuthConfig.Environment.ResourceManager)
		if err != nil {

View on GitHub (pinned to d32a084675)