hashicorp/terraform · error
listing Keys for %s: %+v
Error message
listing Keys for %s: %+v
What it means
AccountDetails.AccountKey (storage_client_helpers.go:66) calls the Azure Resource Manager `storageAccounts/ListKeys` operation (with Kerb expand) to fetch a storage account key for data-plane access. If the ARM call fails, the underlying error (permissions, throttling, connectivity, account not found) is wrapped via %+v.
Source
Thrown at internal/backend/remote-state/azure/storage_client_helpers.go:66
// primaryQueueEndpoint is the Primary Queue Endpoint for the Data Plane API for this Storage Account
// e.g. `https://{account}.queue.core.windows.net`
primaryQueueEndpoint *string
// primaryTableEndpoint is the Primary Table Endpoint for the Data Plane API for this Storage Account
// e.g. `https://{account}.table.core.windows.net`
primaryTableEndpoint *string
}
func (ad *AccountDetails) AccountKey(ctx context.Context, client *storageaccounts.StorageAccountsClient) (*string, error) {
if ad.accountKey != nil {
return ad.accountKey, nil
}
opts := storageaccounts.DefaultListKeysOperationOptions()
opts.Expand = pointer.To(storageaccounts.ListKeyExpandKerb)
listKeysResp, err := client.ListKeys(ctx, ad.StorageAccountId, opts)
if err != nil {
return nil, fmt.Errorf("listing Keys for %s: %+v", ad.StorageAccountId, err)
}
if model := listKeysResp.Model; model != nil && model.Keys != nil {
for _, key := range *model.Keys {
if key.Permissions == nil || key.Value == nil {
continue
}
if *key.Permissions == storageaccounts.KeyPermissionFull {
ad.accountKey = key.Value
break
}
}
}
if ad.accountKey == nil {
return nil, fmt.Errorf("unable to determine the Write Key for %s", ad.StorageAccountId)
}View on GitHub (pinned to c9def3e214)
Solutions
- Grant the principal the Storage Account Key Operator Service Role (or Storage Account Contributor) on the target account.
- Verify storage_account_name and resource_group_name reference an existing account.
- Retry on 429/5xx; for persistent failures inspect the wrapped ARM error text.
- Confirm network/egress to management.azure.com is allowed.
Example fix
# before: principal has only Reader on the storage account # after: assign the key-listing role az role assignment create \ --assignee <principal-id> \ --role "Storage Account Key Operator Service Role" \ --scope "/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Storage/storageAccounts/<acct>"
Defensive patterns
Strategy: retry
Validate before calling
# confirm the identity can list keys before terraform init az role assignment list --assignee <principal-id> \ --scope "/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Storage/storageAccounts/<acct>" \ --query "[].roleDefinitionName" --output tsv | grep -qi "key operator\|storage account contributor" \ || echo "WARN: principal may lack listKeys permission"
Type guard
// narrow a ListKeys error to decide retry vs abort
func isTransientListKeysErr(err error) bool {
var rerr interface{ StatusCode() int }
if errors.As(err, &rerr) {
switch rerr.StatusCode() {
case 408, 429, 500, 502, 503, 504:
return true
}
}
return false
} Try / catch
// backoff/retry ListKeys for transient ARM failures, surface the rest
var key *string
err := backoff.Retry(func() error {
k, e := ad.AccountKey(ctx, keysClient)
if e != nil && isTransientListKeysErr(e) {
return e
}
key = k
return e
}, backoff.NewExponentialBackOff()) Prevention
- Grant the principal the Storage Account Key Operator Service Role on the account.
- Allow egress to management.azure.com from the terraform runtime.
- Treat 429/5xx as transient with backoff; treat 403 as a permission failure.
When it happens
Trigger: The azurerm remote backend, using access-key-based data-plane auth, lists keys for the configured storage_account_name/resource_group_name when the authenticated identity lacks `Microsoft.Storage/storageAccounts/listKeys/action`, the account does not exist, ARM throttled (429), or the network to management.azure.com is unreachable.
Common situations: Service principal without Storage Account Key Operator Service Role / Storage Account Contributor; wrong subscription or resource group; transient ARM 429/5xx; egress/firewall blocking the ARM endpoint.
Related errors
- retrieving key for Storage Account %q: %s
- retrieving container client: %v
- listing blobs: %v
- unable to determine the Write Key for %s
- populating details for %s: `model.Properties` was nil
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/262ca6059dee2718.
Report an issue: GitHub.