{"record":{"id":"facb6313f7e27964","repo":"apache/beam","slug":"error-executing-batch-gcs-request","errorCode":null,"errorMessage":"Error executing batch GCS request","messagePattern":"Error executing batch GCS request","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"sdks/java/extensions/google-cloud-platform-core/src/main/java/org/apache/beam/sdk/extensions/gcp/util/GcsUtilV1.java","lineNumber":964,"sourceCode":"                MAX_CONCURRENT_BATCHES,\n                MAX_CONCURRENT_BATCHES,\n                0L,\n                TimeUnit.MILLISECONDS,\n                new LinkedBlockingQueue<>()));\n\n    List<CompletionStage<Void>> futures = new ArrayList<>();\n    for (final BatchInterface batch : batches) {\n      futures.add(MoreFutures.runAsync(batch::execute, executor));\n    }\n\n    try {\n      try {\n        MoreFutures.get(MoreFutures.allOf(futures));\n      } catch (ExecutionException e) {\n        if (e.getCause() instanceof FileNotFoundException) {\n          throw (FileNotFoundException) e.getCause();\n        }\n        throw new IOException(\"Error executing batch GCS request\", e);\n      } finally {\n        // Give the other batches a chance to complete in error cases.\n        executor.shutdown();\n        if (!executor.awaitTermination(5, TimeUnit.MINUTES)) {\n          LOG.warn(\"Taking over 5 minutes to flush gcs op batches after error\");\n          executor.shutdownNow();\n          if (!executor.awaitTermination(5, TimeUnit.MINUTES)) {\n            LOG.warn(\"Took over 10 minutes to flush gcs op batches after error and interruption.\");\n          }\n        }\n      }\n    } catch (InterruptedException e) {\n      Thread.currentThread().interrupt();\n      throw new IOException(\"Interrupted while executing batch GCS request\", e);\n    }\n  }\n\n  /**","sourceCodeStart":946,"sourceCodeEnd":982,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/extensions/google-cloud-platform-core/src/main/java/org/apache/beam/sdk/extensions/gcp/util/GcsUtilV1.java#L946-L982","documentation":"GcsUtilV1.executeBatches fans GCS operations out across an executor and waits on all futures with MoreFutures.get. If any batch task fails, the ExecutionException is converted into this generic IOException unless the cause is a FileNotFoundException (rethrown as-is). It is an umbrella error; the real per-operation failure is in the cause chain.","triggerScenarios":"Any batched GCS operation (e.g. removeBatches, copy batches) failing inside the executor — network errors, permission errors, or API errors on individual sub-requests.","commonSituations":"Bulk deletes/copies where one object hits a 500 or permission error; transient GCS outages during large batch flushes.","solutions":["Unwrap e.getCause() (and its cause chain) to find the specific failed operation","Check per-object permissions if causes show 403","Retry the batch; individual failed items will surface again","Avoid wrapping operations that produce FileNotFoundException — those are rethrown directly"],"exampleFix":"// before\ntry {\n  gcsUtil.removeBatches(batches);\n} catch (IOException e) {\n  LOG.error(\"batch failed\", e);\n}\n// after\ntry {\n  gcsUtil.removeBatches(batches);\n} catch (IOException e) {\n  Throwable cause = e.getCause();\n  LOG.error(\"batch failed: {}\", cause == null ? e : cause, e);\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"boolean hasFileNotFoundCause(Throwable t) {\n  while (t != null) { if (t instanceof FileNotFoundException) return true; t = t.getCause(); }\n  return false;\n}","tryCatchPattern":"try {\n  gcsUtil.removeBatches(batches);\n} catch (FileNotFoundException e) {\n  // per-library semantics: item missing\n} catch (IOException e) {\n  Throwable root = e; while (root.getCause() != null) root = root.getCause();\n  LOG.error(\"batch op failed: {}\", root.getMessage(), e);\n  throw e;\n}","preventionTips":["Keep batch sizes moderate to limit blast radius","Retry idempotent batch operations","Check per-object permissions before bulk ops","Inspect full cause chain, not just top message"],"tags":["gcs","batch","io"],"backgroundTag":"api-request-failed","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-15T02:17:10.978Z"}