{"record":{"id":"ada27da49276adcf","repo":"hashicorp/terraform","slug":"unable-to-build-authorizer-for-resource-manager-ap","errorCode":null,"errorMessage":"unable to build authorizer for Resource Manager API: %+v","messagePattern":"unable to build authorizer for Resource Manager API: %\\+v","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/backend/remote-state/azure/api_client.go","lineNumber":79,"sourceCode":"\t\tvar err error\n\t\tclient.azureAdStorageAuth, err = auth.NewAuthorizerFromCredentials(ctx, *config.AuthConfig, config.AuthConfig.Environment.Storage)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"unable to build authorizer for Storage API: %+v\", err)\n\t\t}\n\tdefault:\n\t\t// AAD authentication (ARM scope) is required only when no auth method is specified, which falls back to listing the access key via ARM API.\n\t\tarmAuthRequired = true\n\t}\n\n\t// If `config.LookupBlobEndpoint` is true, we need to authenticate with ARM to lookup the blob endpoint\n\tif config.LookupBlobEndpoint {\n\t\tarmAuthRequired = true\n\t}\n\n\tif armAuthRequired {\n\t\tresourceManagerAuth, err := auth.NewAuthorizerFromCredentials(ctx, *config.AuthConfig, config.AuthConfig.Environment.ResourceManager)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"unable to build authorizer for Resource Manager API: %+v\", err)\n\t\t}\n\n\t\t// When using Azure CLI to auth, the user can leave the \"subscription_id\" unspecified. In this case the subscription id is inferred from\n\t\t// the Azure CLI default subscription.\n\t\tif config.SubscriptionID == \"\" {\n\t\t\tif cachedAuth, ok := resourceManagerAuth.(*auth.CachedAuthorizer); ok {\n\t\t\t\tif cliAuth, ok := cachedAuth.Source.(*auth.AzureCliAuthorizer); ok && cliAuth.DefaultSubscriptionID != \"\" {\n\t\t\t\t\tconfig.SubscriptionID = cliAuth.DefaultSubscriptionID\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif config.SubscriptionID == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"subscription id not specified\")\n\t\t}\n\n\t\t// Setup the SA client.\n\t\tclient.storageAccountsClient, err = storageaccounts.NewStorageAccountsClientWithBaseURI(config.AuthConfig.Environment.ResourceManager)\n\t\tif err != nil {","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/backend/remote-state/azure/api_client.go#L61-L97","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before: no creds + lookup_blob_endpoint=true forces ARM auth that fails\nexport ARM_LOOKUP_BLOB_ENDPOINT=true\n# after: either supply ARM creds, or disable lookup and supply endpoint/access_key\nexport ARM_CLIENT_ID=...; export ARM_CLIENT_SECRET=...\nexport ARM_TENANT_ID=...; export ARM_SUBSCRIPTION_ID=...\nexport ARM_LOOKUP_BLOB_ENDPOINT=true","handlingStrategy":"validation","validationCode":"func needsARM(c BackendConfig) bool {\n    return c.AccessKey == \"\" && c.SasToken == \"\" && !c.UseAzureADAuthentication || c.LookupBlobEndpoint\n}\n// If needsARM(cfg) is true, ensure full SP creds or Azure CLI auth is available.","typeGuard":"null","tryCatchPattern":"client, err := azure.NewClient(ctx, cfg)\nif err != nil && strings.Contains(err.Error(), \"unable to build authorizer for Resource Manager API\") {\n    // distinguish: missing creds vs wrong cloud vs CLI not logged in — all surface in the wrapped err\n}","preventionTips":["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."],"tags":["azure","backend","authentication","aad","arm","configuration"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}