{"record":{"id":"05eb8275bcf50e37","repo":"hashicorp/terraform","slug":"querying-cloud-storage-failed-v","errorCode":null,"errorMessage":"querying Cloud Storage failed: %v","messagePattern":"querying Cloud Storage failed: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/backend/remote-state/gcs/backend_state.go","lineNumber":47,"sourceCode":"// state is always returned as the first element in the slice.\nfunc (b *Backend) Workspaces() ([]string, tfdiags.Diagnostics) {\n\tvar diags tfdiags.Diagnostics\n\tctx := context.TODO()\n\n\tstates := []string{backend.DefaultStateName}\n\n\tbucket := b.storageClient.Bucket(b.bucketName)\n\tobjs := bucket.Objects(ctx, &storage.Query{\n\t\tDelimiter: \"/\",\n\t\tPrefix:    b.prefix,\n\t})\n\tfor {\n\t\tattrs, err := objs.Next()\n\t\tif err == iterator.Done {\n\t\t\tbreak\n\t\t}\n\t\tif err != nil {\n\t\t\treturn nil, diags.Append(fmt.Errorf(\"querying Cloud Storage failed: %v\", err))\n\t\t}\n\n\t\tname := path.Base(attrs.Name)\n\t\tif !strings.HasSuffix(name, stateFileSuffix) {\n\t\t\tcontinue\n\t\t}\n\t\tst := strings.TrimSuffix(name, stateFileSuffix)\n\n\t\tif st != backend.DefaultStateName {\n\t\t\tstates = append(states, st)\n\t\t}\n\t}\n\n\tsort.Strings(states[1:])\n\treturn states, diags\n}\n\n// DeleteWorkspace deletes the named workspaces. The \"default\" state cannot be deleted.","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/backend/remote-state/gcs/backend_state.go#L29-L65","documentation":"Workspaces() lists state files in the bucket by calling bucket.Objects(...).Next() in a loop; any non-iterator.Done error from the GCS list API is surfaced here. This is the first network/object call after NewClient, so it commonly reflects bucket-existence or IAM issues rather than auth (auth would already have failed in NewClient).","triggerScenarios":"'terraform workspace list' (or any command that enumerates workspaces) against a bucket the caller can't storage.objects.list, a bucket name that doesn't exist, an invalid prefix, or transient GCS API errors.","commonSituations":"Wrong bucket name in backend config; new SA without 'roles/storage.objectViewer' / 'roles/storage.objectAdmin'; cross-project bucket without granted access; transient 5xx from GCS.","solutions":["Confirm the bucket exists: 'gsutil ls gs://<bucket>' and matches backend.bucket.","Grant the SA 'roles/storage.objectAdmin' (read+list+write) or at minimum 'roles/storage.objectViewer' plus objectViewer on the prefix.","If the %v says 'notFound', fix the bucket name; if 'forbidden', fix IAM; if transient, retry 'terraform workspace list'.","Confirm prefix doesn't escape into a bucket the SA lacks access to."],"exampleFix":"// before: bucket typo\nbucket = \"myco-terraform-state-prod\"\n\n// after\nbucket = \"myco-tfstate-prod\"  # actual bucket\ngsutil iam ch serviceAccount:tf-deployer@proj.iam.gserviceaccount.com:roles/storage.objectAdmin gs://myco-tfstate-prod","handlingStrategy":"retry","validationCode":"// Pre-flight: confirm bucket is listable\nimport \"cloud.google.com/go/storage\"\nfunc bucketListable(ctx context.Context, c *storage.Client, bucket string) error {\n    it := c.Bucket(bucket).Objects(ctx, nil)\n    if _, err := it.Next(); err != nil && err != iterator.Done { return err }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"var states []string\nfor attempt := 0; attempt < 3; attempt++ {\n    var diags tfdiags.Diagnostics\n    states, diags = backend.Workspaces()\n    if !diags.HasErrors() { break }\n    if !isTransientGCS(diags) { break }\n    time.Sleep(backoff(attempt))\n}","preventionTips":["Grant the SA 'roles/storage.objectAdmin' or 'roles/storage.objectViewer' on the bucket.","Validate the bucket name with 'gsutil ls' in a pre-flight CI step.","Use distinct prefixes per project to avoid IAM scope creep."],"tags":["gcs","gcp","workspaces","iam","storage","network"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T21:17:07.882Z"}