apache/hadoop · error · PathIOException

No upload parts in multipart upload

Error message

No upload parts in multipart upload

What it means

PathIOException from WriteOperationHelper.finalizeMultipartUpload when completeMultipartUpload would be invoked with an empty partETags list. Multipart completion requires at least one uploaded part (with its ETag), so S3A refuses rather than send an invalid CompleteMultipartUploadRequest to S3.

Source

Thrown at hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/WriteOperationHelper.java:311

   * @param destKey destination of the commit
   * @param uploadId multipart operation Id
   * @param partETags list of partial uploads
   * @param length length of the upload
   * @param putOptions put object options
   * @param retrying retrying callback
   * @return the result of the operation.
   * @throws IOException on problems.
   */
  @Retries.RetryTranslated
  private CompleteMultipartUploadResponse finalizeMultipartUpload(
      String destKey,
      String uploadId,
      List<CompletedPart> partETags,
      long length,
      PutObjectOptions putOptions,
      Retried retrying) throws IOException {
    if (partETags.isEmpty()) {
      throw new PathIOException(destKey,
          "No upload parts in multipart upload");
    }
    try (AuditSpan span = activateAuditSpan()) {
      CompleteMultipartUploadResponse uploadResult;
      uploadResult = invoker.retry("Completing multipart upload id " + uploadId,
          destKey,
          true,
          retrying,
          () -> {
            final CompleteMultipartUploadRequest.Builder requestBuilder =
                getRequestFactory().newCompleteMultipartUploadRequestBuilder(destKey, uploadId, partETags, putOptions);
            return writeOperationHelperCallbacks.completeMultipartUpload(requestBuilder.build());
          });
      return uploadResult;
    }
  }

  /**

View on GitHub (pinned to 2add963021)

Solutions

  1. Upload at least one part before completing; abort the upload instead when nothing was written
  2. For empty files, use the standard S3AFileSystem.create()/output stream or a direct putObject rather than multipart
  3. If this surfaces inside a committer, upgrade hadoop-aws - bundled committers handle empty-file uploads correctly
  4. Add an assertion partETags.size() > 0 in your buffering code to catch the bug earlier

Example fix

// before
helper.completeMultipartUpload(uploadId, partETags, length); // partETags is empty

// after - guard before completing; empty objects take the putObject path
if (partETags.isEmpty()) {
  helper.abortMultipartUpload(key, uploadId);
  if (length == 0) {
    helper.putObject(key, new byte[0]); // empty object via single PUT
    return;
  }
  throw new IOException("No parts uploaded for " + key + " (" + length + " bytes)");
}
helper.completeMultipartUpload(uploadId, partETags, length);
Defensive patterns

Strategy: validation

Validate before calling

if (partETags == null || partETags.isEmpty()) {
  throw new IOException("Refusing to complete multipart upload "
      + uploadId + " with no uploaded parts");
}
helper.completeMultipartUpload(uploadId, partETags, length);

Try / catch

catch PathIOException with 'No upload parts in multipart upload'; it indicates a caller bug in the write path - fix the code, never retry the same empty completion

Prevention

When it happens

Trigger: Using WriteOperationHelper directly and calling its multipart-completion API before any part was uploaded; buffering implementations or custom committers that never flush a part before completing; empty-input flows that reached the multipart completion path instead of a single putObject.

Common situations: Custom code built on WriteOperationHelper that skips uploadPart for zero-byte inputs; bugs in third-party committers or output formats; jobs writing empty files through a nonstandard path instead of the S3AFileSystem output stream (which handles empty files with a plain putObject).

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/ef3e8cfcc7230c14. Report an issue: GitHub.