{"record":{"id":"bd752be8fb62fe75","repo":"GoogleContainerTools/skaffold","slug":"failed-to-iterate-objects-v","errorCode":null,"errorMessage":"failed to iterate objects: %v","messagePattern":"failed to iterate objects: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/skaffold/gcs/client/native.go","lineNumber":313,"sourceCode":"\n// nativeBucketHandler implements a handler using the Cloud client libraries.\ntype nativeBucketHandler struct {\n\tstorageClient *storage.Client\n\tbucket        *storage.BucketHandle\n}\n\nfunc (nb nativeBucketHandler) ListObjects(ctx context.Context, q *storage.Query) ([]string, error) {\n\tmatches := []string{}\n\tit := nb.bucket.Objects(ctx, q)\n\n\tfor {\n\t\tattrs, err := it.Next()\n\t\tif err == iterator.Done {\n\t\t\tbreak\n\t\t}\n\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to iterate objects: %v\", err)\n\t\t}\n\n\t\tif attrs.Name != \"\" {\n\t\t\tmatches = append(matches, attrs.Name)\n\t\t}\n\t}\n\treturn matches, nil\n}\n\nfunc (nb nativeBucketHandler) DownloadObject(ctx context.Context, localPath, uri string) error {\n\treader, err := nb.bucket.Object(uri).NewReader(ctx)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to read object: %v\", err)\n\t}\n\tdefer reader.Close()\n\n\tfile, err := os.Create(localPath)\n\tif err != nil {","sourceCodeStart":295,"sourceCodeEnd":331,"githubUrl":"https://github.com/GoogleContainerTools/skaffold/blob/a1189de023efc32d4b8e11f395acc678aa555011/pkg/skaffold/gcs/client/native.go#L295-L331","documentation":"ListObjects wraps errors from the storage object iterator while listing bucket objects matching a query (MatchGlob or Prefix). It means listing failed mid-iteration — typically an API-level failure such as the bucket not existing, permission denied, or a transient server/network error. No object names are returned in that case.","triggerScenarios":"Native.DownloadRecursive listing with MatchGlob, or isGCSDirectory listing with Prefix, when the bucket does not exist, the caller lacks storage.objects.list permission, or the iterator hits a 4xx/5xx from the GCS API.","commonSituations":"Typo in the bucket name in gs:// URI (404 storage: bucket doesn't exist); service account missing roles/storage.objectViewer; transient 429/503 from GCS during heavy CI use; network interruption mid-listing.","solutions":["Check the wrapped error: if 'bucket doesn't exist', fix the bucket name in the gs:// URI","Grant the service account roles/storage.objectViewer (or objectAdmin) on the bucket","Retry transient errors (429/5xx); consider backoff for rate limits","Verify network/proxy access to storage.googleapis.com from your environment"],"exampleFix":"// before\nif err := n.DownloadRecursive(ctx, \"gs://my-bukket/dir/**\", dst); err != nil { log.Fatal(err) } // 404\n// after\nif err := gcloudBucketExists(\"my-bucket\") { /* validate first */ }\nif err := n.DownloadRecursive(ctx, \"gs://my-bucket/dir/**\", dst); err != nil { log.Fatal(err) }","handlingStrategy":"retry","validationCode":"func checkBucketReadable(ctx context.Context, bucketName string) error {\n\tclient, err := storage.NewClient(ctx)\n\tif err != nil { return err }\n\tdefer client.Close()\n\t_, err = client.Bucket(bucketName).Attrs(ctx)\n\treturn err // 404 => wrong name, 403 => missing permission\n}\n// call before DownloadRecursive with the parsed bucket name","typeGuard":null,"tryCatchPattern":"err := n.DownloadRecursive(ctx, src, dst)\nif err != nil {\n\tif strings.Contains(err.Error(), \"failed to iterate objects\") {\n\t\t// transient? retry with backoff\n\t\terr = retryBackoff(3, 2*time.Second, func() error {\n\t\t\treturn n.DownloadRecursive(ctx, src, dst)\n\t\t})\n\t}\n\treturn err\n}","preventionTips":["Verify bucket name and existence before listing","Grant storage.objectViewer to the identity used","Add bounded retry with backoff for 429/5xx listing errors","Check the MatchGlob pattern is valid GCS glob syntax"],"tags":["gcs","network","permissions","api-error"],"backgroundTag":"gcs-list-objects-failed","analyzedSha":"a1189de023efc32d4b8e11f395acc678aa555011","analyzedAt":"2026-09-05T12:09:27.064Z","contentChangedAt":"2026-09-05T12:09:27.064Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}