{"record":{"id":"53f4212dc40b6ef4","repo":"benbjohnson/litestream","slug":"failed-to-list-objects-in-gcs-bucket-s-path-s","errorCode":null,"errorMessage":"failed to list objects in GCS bucket %s (path: %s): %w","messagePattern":"failed to list objects in GCS bucket (.+?) \\(path: (.+?)\\): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gs/replica_client.go","lineNumber":107,"sourceCode":"\tc.bkt = c.client.Bucket(c.Bucket)\n\n\treturn nil\n}\n\n// DeleteAll deletes all LTX files.\nfunc (c *ReplicaClient) DeleteAll(ctx context.Context) error {\n\tif err := c.Init(ctx); err != nil {\n\t\treturn err\n\t}\n\n\t// Iterate over every object and delete it.\n\tinternal.OperationTotalCounterVec.WithLabelValues(ReplicaClientType, \"LIST\").Inc()\n\tfor it := c.bkt.Objects(ctx, &storage.Query{Prefix: c.Path + \"/\"}); ; {\n\t\tattrs, err := it.Next()\n\t\tif errors.Is(err, iterator.Done) {\n\t\t\tbreak\n\t\t} else if err != nil {\n\t\t\treturn fmt.Errorf(\"failed to list objects in GCS bucket %s (path: %s): %w\", c.Bucket, c.Path, err)\n\t\t}\n\n\t\tif err := c.bkt.Object(attrs.Name).Delete(ctx); isNotExists(err) {\n\t\t\tcontinue\n\t\t} else if err != nil {\n\t\t\treturn fmt.Errorf(\"gs: cannot delete object %q: %w\", attrs.Name, err)\n\t\t}\n\t\tinternal.OperationTotalCounterVec.WithLabelValues(ReplicaClientType, \"DELETE\").Inc()\n\t}\n\n\t// log.Printf(\"%s(%s): retainer: deleting\", r.db.Path(), r.Name())\n\n\treturn nil\n}\n\n// LTXFiles returns an iterator over all available LTX files for a level.\n// GCS always uses accurate timestamps from metadata since they're included in LIST operations at zero cost.\n// The useMetadata parameter is ignored.","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/gs/replica_client.go#L89-L125","documentation":"DeleteAll() failed while iterating objects under the configured path prefix in the GCS bucket. The underlying storage.Query iterator returned an error other than iterator.Done (e.g. permission denied, bucket missing, transient API failure), wrapped with the bucket and path. Deletion aborts at the first listing error, leaving some objects potentially undeleted.","triggerScenarios":"Calling DeleteAll() when the bucket name is wrong/nonexistent, the credentials lack storage.objects.list permission on the bucket, the GCS API returns a transient 5xx, or the context is canceled mid-iteration.","commonSituations":"Service account missing roles/storage.objectAdmin; typo'd bucket in litestream.yml; bucket deleted externally while litestream runs; GCS outage or rate limiting during a full-replica delete.","solutions":["Check the wrapped cause for the GCS API error (403 vs 404 vs 5xx) and address that specifically","Grant the service account roles/storage.objectAdmin (or objectViewer+objectCreator+objectDeleter) on the bucket","Verify the bucket name in the config with `gsutil ls gs://<bucket>` using the same credentials","Retry — transient 5xx/rate-limit errors are often temporary; consider backoff","Confirm bucket/path prefix matches what litestream actually wrote"],"exampleFix":"# before: permission denied listing\n# after — grant access\ngsutil iam ch serviceAccount:sa@project.iam.gserviceaccount.com:roles/storage.objectAdmin gs://my-bucket","handlingStrategy":"try-catch","validationCode":"it := bkt.Objects(ctx, &storage.Query{Prefix: path + \"/\"})\nif _, err := it.Next(); err != nil && err != iterator.Done {\n    // list permission or bucket problem detected up front\n}","typeGuard":null,"tryCatchPattern":"if err := rc.DeleteAll(ctx); err != nil {\n    if strings.Contains(err.Error(), \"403\") {\n        // grant objectAdmin IAM role\n    }\n    return err\n}","preventionTips":["Grant roles/storage.objectAdmin, not objectViewer, for replication destinations","Validate bucket names in config with a startup check","Monitor GCS 429/5xx rates; add backoff around bulk deletes"],"tags":["gcs","cloud-storage","permissions","listing"],"backgroundTag":"http-error-response","analyzedSha":"4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3","analyzedAt":"2026-09-06T18:29:25.564Z","contentChangedAt":"2026-09-06T18:29:25.564Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}