apache/beam · warning · IOException

Interrupted backoff of file copies with retries, sample: fro

Error message

Interrupted backoff of file copies with retries, sample: from %s to %s due to %s

What it means

Thrown by GcsUtilV1 when the thread sleeping between GCS copy-retry backoff rounds is interrupted. The library restores the interrupt flag before throwing so callers can detect shutdown. It wraps the same sample rewrite error as the retry-exhausted case but signals cancellation rather than failure.

Source

Thrown at sdks/java/extensions/google-cloud-platform-core/src/main/java/org/apache/beam/sdk/extensions/gcp/util/GcsUtilV1.java:1239

        long backOffMillis = backoff.nextBackOffMillis();
        if (backOffMillis == org.apache.beam.sdk.util.BackOff.STOP) {
          throw new IOException(
              String.format(
                  "Error completing file copies with retries, sample: from %s to %s due to %s",
                  sampleErrorOp.getFrom().toString(),
                  sampleErrorOp.getTo().toString(),
                  sampleErrorOp.getLastError()));
        }
        LOG.warn(
            "Retrying with backoff unsuccessful copy requests, sample request: from {} to {} due to {}",
            sampleErrorOp.getFrom(),
            sampleErrorOp.getTo(),
            sampleErrorOp.getLastError());
        try {
          Thread.sleep(backOffMillis);
        } catch (InterruptedException e) {
          Thread.currentThread().interrupt();
          throw new IOException(
              String.format(
                  "Interrupted backoff of file copies with retries, sample: from %s to %s due to %s",
                  sampleErrorOp.getFrom().toString(),
                  sampleErrorOp.getTo().toString(),
                  sampleErrorOp.getLastError()));
        }
      }
      executeBatches(batches);
    }
  }

  LinkedList<RewriteOp> makeRewriteOps(
      Iterable<String> srcFilenames,
      Iterable<String> destFilenames,
      boolean deleteSource,
      boolean ignoreMissingSource,
      boolean ignoreExistingDest)
      throws IOException {

View on GitHub (pinned to 12126d8942)

Solutions

  1. Treat as intentional cancellation: check whether the pipeline/job was cancelled and stop retrying.
  2. If interruption is unexpected, audit thread pools that might interrupt worker threads during shutdown.
  3. Re-run the copy operation after the cancellation cause is resolved.
  4. Keep the Thread.currentThread().interrupt() semantics: don't swallow the flag in surrounding code.

Example fix

null
Defensive patterns

Strategy: try-catch

Try / catch

try {
  gcsUtil.fileCopyRewrite(srcs, dsts);
} catch (IOException e) {
  if (Thread.currentThread().isInterrupted() || e.getMessage().startsWith("Interrupted backoff")) {
    LOG.info("Copy cancelled; skipping");
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: Inside GcsUtilV1.fileCopyRewrite's retry loop, Thread.sleep(backOffMillis) throws InterruptedException because the executing thread was interrupted (e.g. pipeline cancellation, executor shutdown).

Common situations: Cancelling a Dataflow/Beam pipeline mid-copy; application shutdown while a staged-file copy is in progress; a Future.get timeout path that interrupts the worker thread.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/f29e7be6822d6a09. Report an issue: GitHub.