hashicorp/terraform · error

building Storage Accounts client: %+v

Error message

building Storage Accounts client: %+v

What it means

Thrown by Azure buildClient when storageaccounts.NewStorageAccountsClientWithBaseURI(config.AuthConfig.Environment.ResourceManager) returns an error. This constructor only fails when the ARM base URI is empty or not a parseable URL, so the root cause is the environment metadata rather than credentials.

Solutions

  1. Verify the environment name is one Terraform recognizes (AzurePublicCloud, AzureChinaCloud, AzureUSGovernmentCloud, AzureGermanCloud, or a properly configured custom environment).
  2. For air-gapped/custom clouds, ensure the environment metadata fully defines the ResourceManager endpoint URL and is reachable.
  3. If overriding endpoints via env vars, supply a complete, parseable ARM base URL.
  4. Update the go-azure-sdk dependency to the version Terraform core expects to avoid struct/endpoint mismatches.

Example fix

# before: custom env with no ARM endpoint
export ARM_ENVIRONMENT="MyCloud"   # not registered -> building Storage Accounts client fails
# after: use a supported env or register metadata
export ARM_ENVIRONMENT="AzurePublicCloud"
Defensive patterns

Strategy: validation

Validate before calling

func validEnv(env environments.Environment) error {
    if env.ResourceManager == nil || *env.ResourceManager == "" {
        return fmt.Errorf("environment has no ResourceManager endpoint")
    }
    if _, err := url.Parse(*env.ResourceManager); err != nil {
        return fmt.Errorf("ResourceManager endpoint is not a URL: %w", err)
    }
    return nil
}

Type guard

null

Try / catch

client, err := azure.NewClient(ctx, cfg)
if err != nil && strings.Contains(err.Error(), "building Storage Accounts client") {
    // environment metadata is wrong; verify ARM_ENVIRONMENT / metadata URL
}

Prevention

When it happens

Trigger: config.AuthConfig.Environment.ResourceManager is empty or malformed, so the go-azure-sdk storageaccounts client cannot be constructed. Happens with a custom/incorrect environment name, a hand-built environments.Environment missing the ResourceManager endpoint, or a version skew in go-azure-sdk that changed how base URIs are resolved.

Common situations: Using environment=... with an unsupported name (typo of 'AzurePublicCloud', a private cloud name not registered), overriding ARM_ENDPOINT or metadata_url with a bad URL, or a stale go-azure-sdk dependency that no longer matches the environment struct shape.

Related errors


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

Appendix: source

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

		}

		// 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 {
			return nil, fmt.Errorf("building Storage Accounts client: %+v", err)
		}
		client.configureClient(client.storageAccountsClient.Client, resourceManagerAuth)

		// Populating the storage account detail
		storageAccountId := commonids.NewStorageAccountID(config.SubscriptionID, config.ResourceGroupName, client.storageAccountName)
		resp, err := client.storageAccountsClient.GetProperties(ctx, storageAccountId, storageaccounts.DefaultGetPropertiesOperationOptions())
		if err != nil {
			return nil, fmt.Errorf("retrieving %s: %+v", storageAccountId, err)
		}
		if resp.Model == nil {
			return nil, fmt.Errorf("retrieving %s: model was nil", storageAccountId)
		}
		client.accountDetail, err = populateAccountDetails(storageAccountId, *resp.Model)
		if err != nil {
			return nil, fmt.Errorf("populating details for %s: %+v", storageAccountId, err)
		}
	}

View on GitHub (pinned to d32a084675)