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
- Inspect the wrapped auth error for the specific missing or invalid credential field.
- Provide a complete service principal (client_id, client_secret or cert or OIDC, tenant_id, subscription_id) usable against ARM.
- 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.
- Avoid needing ARM entirely by supplying an access_key or sas_token directly (then lookup_blob_endpoint stays false).
- 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
- If you only need blob access, supply an access_key or sas_token to avoid ARM auth entirely.
- When lookup_blob_endpoint is not needed, leave it false so ARM auth is not forced.
- For CLI auth, run `az login` and `az account set` in the same shell/context as Terraform.
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
- unable to build authorizer for Storage API: %+v
- building Storage Accounts client: %+v
- sasToken cannot be empty
- subscription id not specified
- Error loading credentials
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)