apache/flink · warning · IOException

Interrupted while uploading object for key: {}

Error message

Interrupted while uploading object for key: {}

What it means

In the S3TransferManager upload path, the code blocks on fileUpload.completionFuture().get(). If that thread is interrupted (task cancellation, shutdown hook, checkpoint timeout cancelling the operator), the future is cancelled with mayInterruptIfRunning, the interrupt flag is restored on the current thread, and this IOException is thrown. Restoring the interrupt status matters: Flink relies on it to propagate cancellation cleanly.

Source

Thrown at flink-filesystems/flink-s3-fs-native/src/main/java/org/apache/flink/fs/s3native/writer/NativeS3ObjectOperations.java:273

                                                if (encryptionConfig.hasEncryptionContext()) {
                                                    req.ssekmsEncryptionContext(
                                                            encryptionConfig
                                                                    .serializeEncryptionContext());
                                                }
                                            }
                                        }
                                    })
                            .source(inputFile.toPath())
                            .build();

            FileUpload fileUpload = transferManager.uploadFile(uploadRequest);
            CompletedFileUpload completedUpload;
            try {
                completedUpload = fileUpload.completionFuture().get();
            } catch (InterruptedException e) {
                fileUpload.completionFuture().cancel(true);
                Thread.currentThread().interrupt();
                throw new IOException("Interrupted while uploading object for key: " + key, e);
            } catch (ExecutionException e) {
                throw new IOException(
                        "Failed to async upload object for key: " + key, e.getCause());
            }
            return new PutObjectResult(completedUpload.response().eTag());
        } catch (IOException e) {
            throw e;
        } catch (Exception e) {
            throw new IOException("Failed to async upload object for key: " + key, e);
        }
    }

    /**
     * Completes a multipart upload by assembling previously uploaded parts.
     *
     * <p><b>Recovery Scenario:</b> If a {@link NoSuchUploadException} is thrown, this may indicate
     * that the upload was already completed (possibly by a previous attempt during recovery). In
     * this case, we check if the object exists and return its metadata. This handles the scenario

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Treat as cancellation, not data loss: do not swallow it; let the IOException propagate so Flink's cancellation machinery finishes cleanup (abort of the multipart upload happens via the writer's cleanup path).
  2. If your operator catches InterruptedException-shaped errors, ensure you re-interrupt/rethrow rather than retrying the upload — the transfer was cancelled(true) and cannot be resumed.
  3. To reduce interruption windows, keep individual uploads (part sizes) bounded so cancellation lands between uploads.
  4. On restart, rely on RecoverableWriter state to re-upload from the last persisted part instead of restarting the file from zero.

Example fix

// before — swallowing an interrupted upload and retrying
try { ops.putObject(key, file); }
catch (IOException e) { ops.putObject(key, file); } // may retry a cancelled transfer

// after — honor cancellation
try { ops.putObject(key, file); }
catch (IOException e) {
    if (Thread.currentThread().isInterrupted()) throw e; // propagate cancellation
    throw e;
}
Defensive patterns

Strategy: try-catch

Try / catch

catch (IOException e) { if (Thread.currentThread().isInterrupted() || (e.getCause() instanceof InterruptedException)) { cleanupAndPropagateForCancellation(e); /* no retry */ } else throw e; }

Prevention

When it happens

Trigger: Flink cancels the job/task while a TransferManager upload of a part or small object is in flight; a checkpoint timeout triggers operator thread interruption; user code interrupts the writer thread; test harness teardown interrupts upload threads.

Common situations: Job cancellation during large S3 writes; failover where the writer thread is interrupted mid-upload; abrupt MiniCluster shutdown in tests leaving uploads unfinished (normally benign — the upload is cancelled by design).

Related errors


AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14). Data as JSON: /api/errors/fc4d6b0ccb9da51c. Report an issue: GitHub.