hashicorp/terraform · error
retrieving : %+v
Error message
retrieving %s: %+v
What it means
Thrown by Azure buildClient when storageAccountsClient.GetProperties returns an error reading the storage account via ARM. The %s is the full storage account Resource ID (/subscriptions/.../resourceGroups/.../providers/Microsoft.Storage/storageAccounts/<name>); %+v is the ARM/SDK error. This is the most common Azure backend init failure because it depends on the account existing and the SP having Reader access.
Solutions
- Read the wrapped %+v: 404 means wrong name/group/subscription, 403 means missing Reader role, 429 means throttle, 5xx means retry.
- Confirm storage_account_name and resource_group_name match a real account (cross-check with `az storage account show`).
- Grant the SP 'Storage Account Contributor' or 'Reader' on the resource group or account.
- For transient errors (429/5xx/network), retry after a short backoff; for persistent failures, fix the underlying permission/existence problem.
- Verify the account is in the subscription_id you supplied.
Example fix
# grant the SP read access so GetProperties succeeds az role assignment create \ --assignee $ARM_CLIENT_ID \ --role "Storage Account Contributor" \ --scope /subscriptions/$ARM_SUBSCRIPTION_ID/resourceGroups/$RG/providers/Microsoft.Storage/storageAccounts/$ACCOUNT
Defensive patterns
Strategy: retry
Validate before calling
// Preflight: confirm the account exists and is readable.
func accountReadable(sub, rg, name string) error {
// wrap an `az storage account show --subscription $sub -g $rg -n $name` call
return nil
} Type guard
null
Try / catch
client, err := azure.NewClient(ctx, cfg)
if err != nil && strings.Contains(err.Error(), "retrieving") {
code := azureArmCode(err)
switch code {
case 404: // wrong name/group/sub
case 403: // grant Reader/Contributor
case 429, 500, 502, 503: // retry with backoff
}
} Prevention
- Grant the SP 'Storage Account Contributor' (or Reader + key-listing rights) on the account or resource group.
- Double-check storage_account_name and resource_group_name spellings and the subscription they live in.
- For transient ARM failures, retry with exponential backoff; for 403/404 fix permissions/existence first.
When it happens
Trigger: armAuthRequired is true and the ARM GET on the storage account resource fails: account does not exist, wrong resource_group_name, wrong subscription, the authenticated principal lacks Microsoft.Storage/storageAccounts/read, ARM throttled the request, or a transient network/ARM-service error.
Common situations: Typo in storage_account_name or resource_group_name; SP with no RBAC role on the storage account or resource group; account lives in a different subscription than subscription_id; ARM service incident or throttling; private networking blocking the ARM endpoint.
Related errors
- retrieving key for Storage Account
- retrieving : model was nil
- building Storage Accounts client: %+v
- Failed to retrieve workspace
- populating details for
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/241acdadeb158434.
Report an issue: GitHub.
Appendix: source
Thrown at internal/backend/remote-state/azure/api_client.go:106
}
}
}
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)
}
}
return &client, nil
}
func (c *Client) getBlobClient(ctx context.Context) (bc *blobs.Client, err error) {
if c.blobsClient != nil {
return c.blobsClient, nil
}
View on GitHub (pinned to d32a084675)