{"record":{"id":"777c783df43bcba2","repo":"hashicorp/terraform","slug":"listing-blobs-v","errorCode":null,"errorMessage":"listing blobs: %v","messagePattern":"listing blobs: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/backend/remote-state/azure/backend_state.go","lineNumber":41,"sourceCode":"\t// reduce the chance of name conflicts with existing objects.\n\tkeyEnvPrefix = \"env:\"\n)\n\nfunc (b *Backend) Workspaces() ([]string, tfdiags.Diagnostics) {\n\tvar diags tfdiags.Diagnostics\n\tprefix := b.keyName + keyEnvPrefix\n\tparams := containers.ListBlobsInput{\n\t\tPrefix: &prefix,\n\t}\n\n\tctx := newCtx()\n\tclient, err := b.apiClient.getContainersClient(ctx)\n\tif err != nil {\n\t\treturn nil, diags.Append(fmt.Errorf(\"retrieving container client: %v\", err))\n\t}\n\tresp, err := client.ListBlobs(ctx, b.containerName, params)\n\tif err != nil {\n\t\treturn nil, diags.Append(fmt.Errorf(\"listing blobs: %v\", err))\n\t}\n\n\tenvs := map[string]struct{}{}\n\tfor _, obj := range resp.Blobs.Blobs {\n\t\tkey := obj.Name\n\t\tif strings.HasPrefix(key, prefix) {\n\t\t\tname := strings.TrimPrefix(key, prefix)\n\t\t\t// we store the state in a key, not a directory\n\t\t\tif strings.Contains(name, \"/\") {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tenvs[name] = struct{}{}\n\t\t}\n\t}\n\n\tresult := []string{backend.DefaultStateName}\n\tfor name := range envs {","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/backend/remote-state/azure/backend_state.go#L23-L59","documentation":"A wrapper error from Backend.Workspaces (backend_state.go:39-41). After the containers client is built, the backend calls client.ListBlobs against the storage container to enumerate workspace state files; if that data-plane call fails, this error is returned. Unlike error 148 this is a real network/auth failure against the storage data plane, not a client-construction problem.","triggerScenarios":"Produced at backend_state.go:39-41 during workspace enumeration when client.ListBlobs(ctx, b.containerName, params) returns an error. The prefix used is '<keyName>env:'.","commonSituations":"Wrong container_name; the credential lacks 'Container/blob/list' data-plane permission; the container was deleted; network/firewall blocking the storage endpoint (storage account firewall set to selected networks); a SAS token that expired.","solutions":["Confirm container_name matches an existing container: az storage container list --account-name <account> --auth-mode login","Grant the principal 'Storage Blob Data Contributor' for data-plane access (RBAC) or widen the SAS token permissions","Check storage account network firewall allows your client IP / VNet","If using a SAS token, confirm it has not expired and includes List ('l') permission"],"exampleFix":"# before: storage firewall blocks the runner\naz storage account update -n mystage --default-action Deny\n\n# after: allow the runner's IP (or enable the managed identity / VNet rule)\naz storage account update -n mystage --default-action Deny \\\n  --bypass AzureServices\naz storage account network-rule add -n mystage --ip-address 203.0.113.10","handlingStrategy":"retry","validationCode":"# Pre-flight: list blobs to confirm data-plane access and container name\naz storage blob list --account-name \"$ARM_STORAGE_ACCOUNT_NAME\" -c \"$ARM_CONTAINER_NAME\" --prefix \"${ARM_KEY}env:\" --auth-mode login >/dev/null 2>&1 \\\n  && echo \"OK: can list workspace blobs\" || echo \"WARN: listing failed -> error 149 possible (container name / firewall / permissions)\"","typeGuard":null,"tryCatchPattern":"# Bash: retry transient data-plane listing with backoff\nlist_workspace_blobs() {\n  for attempt in 1 2 3 4 5; do\n    if terraform workspace list; then return 0; fi\n    sleep $((attempt * attempt))\n  done\n  echo \"workspace list failed after retries; check storage firewall/permissions\"\n  return 1\n}","preventionTips":["Grant 'Storage Blob Data Contributor' (data-plane) or a SAS with list permission","Allowlist your runner IP / VNet in the storage account network firewall","Use --auth-mode login (AAD) in CI to avoid expiring SAS tokens"],"tags":["azure","storage","data-plane","network","workspace","list"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T20:17:04.800Z"}