All Products
Search
Document Center

Object Storage Service:Multipart upload

Last Updated:Dec 17, 2025

Uploading large files can be challenging due to network interruptions and long transfer times. Multipart upload addresses these issues by splitting a file into smaller parts, transferring them concurrently, and enabling resumable uploads. This method optimizes performance and is highly effective for transfers over unstable networks.

How it works

Multipart upload splits a large file into smaller, independently processed parts. Each part is transferred and verified separately. If a single part fails to upload, you only need to re-upload the failed part, not the entire file. An UploadId identifies the task, ensuring all parts are correctly associated with it. The core process consists of three steps:

  1. Initialize the upload: Call the InitiateMultipartUpload operation to create a multipart upload and obtain a unique UploadId to identify subsequent operations.

  2. Upload file part data: Concurrently upload the file in parts, each ranging from 100 KB to 5 GB in size. Resumable upload is supported.

  3. Complete the upload by combining parts: Call the CompleteMultipartUpload operation to combine all parts in order of their part numbers into a complete object.

image

Implement multipart upload for large files

Important

Due to a policy change to improve compliance and security, starting March 20, 2025, new OSS users must use a custom domain name (CNAME) to perform data API operations on OSS buckets located in Chinese mainland regions. Default public endpoints are restricted for these operations. Refer to the official announcement for a complete list of the affected operations. If you access your data via HTTPS, you must bind a valid SSL Certificate to your custom domain. This is mandatory for OSS Console access, as the console enforces HTTPS.

Use graphical tools, command-line tools, or SDKs to implement multipart upload as needed.

Note
  • The OSS console does not support multipart upload.

  • You can upload encrypted compressed files, but you cannot upload directories.

Use tools for automatic part splitting

For daily development, testing, O&M, or manual uploads, use graphical or command-line tools. These tools automatically handle the part-splitting logic and are easy to use.

  • Graphical management tool: OSS Browser

    When you use ossbrowser 2.0 to upload files, multipart upload is enabled by default. ossbrowser provides a visual interface to monitor upload progress and status.

  • ossutil

    When you use the cp command of ossutil 2.0 to upload a file, the tool automatically enables multipart upload for files larger than 100 MiB to improve the success rate and transfer efficiency of large file uploads. To manually control the multipart upload process, use the initiate-multipart-upload, upload-part, and complete-multipart-upload commands together.

    ossutil cp example.zip oss://example-bucket

Programmatic control with SDKs

SDKs for various languages encapsulate multipart upload operations, supporting custom part sizes, concurrency control, and error handling. The following sections provide multipart upload examples for common SDKs. For examples in other languages, see the sample code in SDK Reference.

Before running the code, install the appropriate SDK and configure your access credentials as environment variables. If you use a RAM user or RAM role, you must also grant the required permissions. For more information, see API permissions.

Java SDK V2

import com.aliyun.sdk.service.oss2.OSSClient;
import com.aliyun.sdk.service.oss2.credentials.CredentialsProvider;
import com.aliyun.sdk.service.oss2.credentials.StaticCredentialsProvider;
import com.aliyun.sdk.service.oss2.io.BoundedInputStream;
import com.aliyun.sdk.service.oss2.models.*;
import com.aliyun.sdk.service.oss2.transport.BinaryData;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * Sample OSS multipart upload.
 * Implements multipart upload for large files.
 */
public class MultipartUpload {

    public static void main(String[] args) {
        // Obtain access credentials from environment variables.
        String accessKeyId = System.getenv("OSS_ACCESS_KEY_ID");
        String accessKeySecret = System.getenv("OSS_ACCESS_KEY_SECRET");

        // Set the OSS region and endpoint.
        String region = "cn-hangzhou";
        String endpoint = "oss-cn-hangzhou.aliyuncs.com";

        // Configure bucket and file information.
        String bucket = "example-bucket";
        String key = "dest.jpg";
        String filePath = "dest.jpg";

        // Create a credential provider.
        CredentialsProvider provider = new StaticCredentialsProvider(accessKeyId, accessKeySecret);

        // Initialize the OSS client.
        OSSClient client = OSSClient.newBuilder()
                .credentialsProvider(provider)
                .region(region)
                .endpoint(endpoint)
                .build();

        try {
            // Step 1: Initialize the multipart upload.
            InitiateMultipartUploadResult initiateResult = client.initiateMultipartUpload(
                    InitiateMultipartUploadRequest.newBuilder()
                            .bucket(bucket)
                            .key(key)
                            .build());

            String uploadId = initiateResult.initiateMultipartUpload().uploadId();
            System.out.printf("Initiated multipart upload successfully. Status code: %d, Request ID: %s, Upload ID: %s\n",
                    initiateResult.statusCode(), initiateResult.requestId(), uploadId);

            // Step 2: Upload parts.
            File file = new File(filePath);
            long fileSize = file.length();
            long partSize = 100 * 1024; // 100 KB per part.
            int partNumber = 1;
            List<Part> uploadParts = new ArrayList<>();

            for (long start = 0; start < fileSize; start += partSize) {
                long curPartSize = Math.min(partSize, fileSize - start);

                // Read a file part and upload it.
                try (InputStream is = new FileInputStream(file)) {
                    is.skip(start);
                    BoundedInputStream boundedInputStream = new BoundedInputStream(is, curPartSize);

                    // Upload the part.
                    UploadPartResult partResult = client.uploadPart(UploadPartRequest.newBuilder()
                            .bucket(bucket)
                            .key(key)
                            .uploadId(uploadId)
                            .partNumber((long) partNumber)
                            .body(BinaryData.fromStream(boundedInputStream))
                            .build());

                    System.out.printf("Status code: %d, Request ID: %s, Part number: %d, ETag: %s\n",
                            partResult.statusCode(), partResult.requestId(), partNumber, partResult.eTag());

                    uploadParts.add(Part.newBuilder()
                            .partNumber((long) partNumber)
                            .eTag(partResult.eTag())
                            .build());
                }
                partNumber++;
            }

            // Step 3: Complete the multipart upload.
            uploadParts.sort((p1, p2) -> p1.partNumber().compareTo(p2.partNumber()));

            CompleteMultipartUpload completeMultipartUpload = CompleteMultipartUpload.newBuilder()
                    .parts(uploadParts)
                    .build();

            CompleteMultipartUploadResult completeResult = client.completeMultipartUpload(
                    CompleteMultipartUploadRequest.newBuilder()
                            .bucket(bucket)
                            .key(key)
                            .uploadId(uploadId)
                            .completeMultipartUpload(completeMultipartUpload)
                            .build());

            System.out.printf("Completed multipart upload. Status code: %d, Request ID: %s, Bucket: %s, Key: %s, Location: %s, ETag: %s\n",
                    completeResult.statusCode(), completeResult.requestId(), 
                    completeResult.completeMultipartUpload().bucket(),
                    completeResult.completeMultipartUpload().key(), 
                    completeResult.completeMultipartUpload().location(),
                    completeResult.completeMultipartUpload().eTag());

        } catch (Exception e) {
            System.out.printf("Error:\n%s", e);
            e.printStackTrace();
        } finally {
            // Close the client.
            try {
                client.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

Java SDK V1

import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.*;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * Sample OSS multipart upload (V1 SDK).
 * Implements multipart upload for large files.
 */
public class MultipartUpload {

    public static void main(String[] args) {
        // Obtain access credentials from environment variables.
        String accessKeyId = System.getenv("OSS_ACCESS_KEY_ID");
        String accessKeySecret = System.getenv("OSS_ACCESS_KEY_SECRET");

        // Set the OSS region and endpoint.
        String region = "cn-hangzhou";
        String endpoint = "oss-cn-hangzhou.aliyuncs.com";

        // Configure bucket and file information.
        String bucketName = "example-bucket";
        String objectName = "dest.jpg";
        String filePath = "dest.jpg";

        // Create a credential provider.
        DefaultCredentialProvider provider = new DefaultCredentialProvider(accessKeyId, accessKeySecret);

        // Configure client parameters.
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);

        // Initialize the OSS client.
        OSS ossClient = OSSClientBuilder.create()
                .credentialsProvider(provider)
                .clientConfiguration(clientBuilderConfiguration)
                .region(region)
                .endpoint(endpoint)
                .build();

        try {
            // Step 1: Initialize the multipart upload.
            InitiateMultipartUploadRequest initiateRequest = new InitiateMultipartUploadRequest(bucketName, objectName);
            InitiateMultipartUploadResult initiateResult = ossClient.initiateMultipartUpload(initiateRequest);
            String uploadId = initiateResult.getUploadId();
            System.out.printf("Initiated multipart upload successfully. Upload ID: %s\n", uploadId);

            // Step 2: Upload parts.
            File file = new File(filePath);
            long fileLength = file.length();
            long partSize = 100 * 1024L; // 100 KB per part.

            // Calculate the number of parts.
            int partCount = (int) (fileLength / partSize);
            if (fileLength % partSize != 0) {
                partCount++;
            }

            // Save the ETags of uploaded parts.
            List<PartETag> partETags = new ArrayList<>();

            // Traverse and upload parts.
            for (int i = 0; i < partCount; i++) {
                long startPos = i * partSize;
                long curPartSize = (i + 1 == partCount) ? (fileLength - startPos) : partSize;

                // Create an upload part request.
                UploadPartRequest uploadPartRequest = new UploadPartRequest();
                uploadPartRequest.setBucketName(bucketName);
                uploadPartRequest.setKey(objectName);
                uploadPartRequest.setUploadId(uploadId);
                uploadPartRequest.setPartNumber(i + 1);
                uploadPartRequest.setPartSize(curPartSize);

                // Read a file part and upload it.
                try (InputStream instream = new FileInputStream(file)) {
                    instream.skip(startPos);
                    uploadPartRequest.setInputStream(instream);

                    UploadPartResult uploadPartResult = ossClient.uploadPart(uploadPartRequest);
                    partETags.add(uploadPartResult.getPartETag());

                    System.out.printf("Uploaded part %d/%d successfully. ETag: %s\n",
                            i + 1, partCount, uploadPartResult.getPartETag().getETag());
                }
            }

            // Step 3: Complete the multipart upload.
            CompleteMultipartUploadRequest completeRequest = new CompleteMultipartUploadRequest(
                    bucketName, objectName, uploadId, partETags);
            CompleteMultipartUploadResult completeResult = ossClient.completeMultipartUpload(completeRequest);

            System.out.printf("Completed multipart upload. ETag: %s\n", completeResult.getETag());

        } catch (Exception e) {
            System.out.printf("Error: %s\n", e.getMessage());
            e.printStackTrace();
        } finally {
            // Close the client.
            ossClient.shutdown();
        }
    }
}

Python SDK V2

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Sample multipart upload using OSS Python SDK V2.
# Implements multipart upload for large files.

import alibabacloud_oss_v2 as oss
import os

def main():
    # Obtain access credentials from environment variables.
    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    # Load the default configurations of the SDK.
    config = oss.config.load_default()
    config.credentials_provider = credentials_provider

    # Set the OSS region and endpoint.
    config.region = "cn-hangzhou"
    config.endpoint = "oss-cn-hangzhou.aliyuncs.com"

    # Initialize the OSS client.
    client = oss.Client(config)

    # Configure bucket and file information.
    bucket = "example-bucket"
    key = "dest.jpg"
    file_path = "dest.jpg"

    try:
        # Step 1: Initialize the multipart upload.
        initiate_result = client.initiate_multipart_upload(
            oss.InitiateMultipartUploadRequest(
                bucket=bucket,
                key=key
            ))

        upload_id = initiate_result.upload_id
        print(f"Initiated multipart upload successfully. Status code: {initiate_result.status_code}, "
              f"Request ID: {initiate_result.request_id}, Upload ID: {upload_id}")

        # Step 2: Upload parts.
        file_size = os.path.getsize(file_path)
        part_size = 100 * 1024  # 100 KB per part.
        part_number = 1
        upload_parts = []
        offset = 0

        with open(file_path, 'rb') as f:
            while offset < file_size:
                # Calculate the size of the current part.
                current_part_size = min(part_size, file_size - offset)
                
                # Read the part data.
                f.seek(offset)
                part_data = f.read(current_part_size)

                # Upload the part.
                part_result = client.upload_part(
                    oss.UploadPartRequest(
                        bucket=bucket,
                        key=key,
                        upload_id=upload_id,
                        part_number=part_number,
                        body=part_data
                    ))

                print(f"Status code: {part_result.status_code}, Request ID: {part_result.request_id}, "
                      f"Part number: {part_number}, ETag: {part_result.etag}")

                # Record the information of the uploaded part.
                upload_parts.append(oss.UploadPart(
                    part_number=part_number,
                    etag=part_result.etag
                ))

                offset += current_part_size
                part_number += 1

        # Step 3: Complete the multipart upload.
        upload_parts.sort(key=lambda p: p.part_number)

        complete_result = client.complete_multipart_upload(
            oss.CompleteMultipartUploadRequest(
                bucket=bucket,
                key=key,
                upload_id=upload_id,
                complete_multipart_upload=oss.CompleteMultipartUpload(
                    parts=upload_parts
                )
            ))

        print(f"Completed multipart upload. Status code: {complete_result.status_code}, "
              f"Request ID: {complete_result.request_id}, "
              f"Bucket: {complete_result.bucket}, "
              f"Key: {complete_result.key}, "
              f"Location: {complete_result.location}, "
              f"ETag: {complete_result.etag}")

    except Exception as e:
        print(f"Error: {e}")
        raise

if __name__ == "__main__":
    main()

Python SDK V1

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Sample multipart upload using OSS Python SDK V1.
# Implements multipart upload for large files.

import os
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
from oss2 import SizedFileAdapter
from oss2.models import PartInfo

def main():
    # Obtain access credentials from environment variables.
    auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())

    # Set the OSS region and endpoint.
    region = "cn-hangzhou"
    endpoint = "oss-cn-hangzhou.aliyuncs.com"

    # Configure bucket and file information.
    bucket_name = "example-bucket"
    key = "dest.jpg"
    file_path = "dest.jpg"

    # Initialize the OSS bucket.
    bucket = oss2.Bucket(auth, endpoint, bucket_name, region=region)

    try:
        # Step 1: Initialize the multipart upload.
        upload_id = bucket.init_multipart_upload(key).upload_id
        print(f"Initiated multipart upload successfully. Upload ID: {upload_id}")

        # Step 2: Upload parts.
        file_size = os.path.getsize(file_path)
        part_size = 100 * 1024  # 100 KB per part.
        part_number = 1
        parts = []
        offset = 0

        with open(file_path, 'rb') as fileobj:
            while offset < file_size:
                # Calculate the size of the current part.
                current_part_size = min(part_size, file_size - offset)

                # Upload the part.
                result = bucket.upload_part(
                    key,
                    upload_id,
                    part_number,
                    SizedFileAdapter(fileobj, current_part_size)
                )

                print(f"Part number: {part_number}, ETag: {result.etag}")

                # Record the information of the uploaded part.
                parts.append(PartInfo(part_number, result.etag))

                offset += current_part_size
                part_number += 1

        # Step 3: Complete the multipart upload.
        result = bucket.complete_multipart_upload(key, upload_id, parts)
        print(f"Completed multipart upload. ETag: {result.etag}")

    except Exception as e:
        print(f"Error: {e}")
        raise

if __name__ == "__main__":
    main()

Go SDK V2

package main

// Sample multipart upload using OSS Go SDK V2.
// Implements multipart upload for large files.

import (
	"context"
	"fmt"
	"io"
	"os"

	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)

func main() {
	// Obtain access credentials from environment variables.
	// Configure the OSS client, set the credential provider and endpoint.
	config := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion("cn-hangzhou").
		WithEndpoint("oss-cn-hangzhou.aliyuncs.com")

	// Initialize the OSS client.
	client := oss.NewClient(config)

	// Configure bucket and file information.
	bucket := "example-bucket"
	key := "dest.jpg"
	filePath := "dest.jpg"

	// Step 1: Initialize the multipart upload.
	initResult, err := client.InitiateMultipartUpload(context.TODO(), &oss.InitiateMultipartUploadRequest{
		Bucket: oss.Ptr(bucket),
		Key:    oss.Ptr(key),
	})
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}

	uploadId := *initResult.UploadId
	fmt.Printf("Initiated multipart upload successfully. Upload ID: %s\n", uploadId)

	// Step 2: Upload parts.
	file, err := os.Open(filePath)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}
	defer file.Close()

	fileInfo, err := file.Stat()
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}

	fileSize := fileInfo.Size()
	partSize := int64(100 * 1024) // 100 KB per part.
	partNumber := int32(1)
	var parts []oss.UploadPart

	for offset := int64(0); offset < fileSize; offset += partSize {
		// Calculate the size of the current part.
		currentPartSize := partSize
		if offset+partSize > fileSize {
			currentPartSize = fileSize - offset
		}

		// Read the part data.
		file.Seek(offset, 0)
		partData := io.LimitReader(file, currentPartSize)

		// Upload the part.
		partResult, err := client.UploadPart(context.TODO(), &oss.UploadPartRequest{
			Bucket:     oss.Ptr(bucket),
			Key:        oss.Ptr(key),
			UploadId:   oss.Ptr(uploadId),
			PartNumber: partNumber,
			Body:       partData,
		})
		if err != nil {
			fmt.Printf("Error: %v\n", err)
			return
		}

		fmt.Printf("Part number: %d, ETag: %s\n", partNumber, *partResult.ETag)

		// Record the information of the uploaded part.
		parts = append(parts, oss.UploadPart{
			PartNumber: partNumber,
			ETag:       partResult.ETag,
		})

		partNumber++
	}

	// Step 3: Complete the multipart upload.
	completeResult, err := client.CompleteMultipartUpload(context.TODO(), &oss.CompleteMultipartUploadRequest{
		Bucket:   oss.Ptr(bucket),
		Key:      oss.Ptr(key),
		UploadId: oss.Ptr(uploadId),
		CompleteMultipartUpload: &oss.CompleteMultipartUpload{
			Parts: parts,
		},
	})
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}

	fmt.Printf("Completed multipart upload. Bucket: %s, Key: %s, Location: %s, ETag: %s\n",
		*completeResult.Bucket, *completeResult.Key, *completeResult.Location, *completeResult.ETag)
}

Go SDK V1

package main

// Sample multipart upload using OSS Go SDK V1.
// Implements multipart upload for large files.

import (
	"fmt"
	"os"

	"github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {
	// Obtain access credentials from environment variables.
	provider, _ := oss.NewEnvironmentVariableCredentialsProvider()

	// Create an OSS client instance.
	client, _ := oss.New(
		"oss-cn-hangzhou.aliyuncs.com",
		"",
		"",
		oss.SetCredentialsProvider(&provider),
		oss.AuthVersion(oss.AuthV4),
		oss.Region("cn-hangzhou"),
	)

	// Obtain the bucket object.
	bucket, _ := client.Bucket("example-bucket")

	// Configure file information.
	key := "dest.jpg"
	filePath := "dest.jpg"

	// Step 1: Initialize the multipart upload.
	imur, err := bucket.InitiateMultipartUpload(key)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}

	fmt.Printf("Initiated multipart upload successfully. Upload ID: %s\n", imur.UploadID)

	// Step 2: Upload parts.
	file, err := os.Open(filePath)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}
	defer file.Close()

	fileInfo, err := file.Stat()
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}

	fileSize := fileInfo.Size()
	partSize := int64(100 * 1024) // 100 KB per part.

	// Split the file into parts.
	chunks, err := oss.SplitFileByPartSize(filePath, partSize)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}

	var parts []oss.UploadPart
	for _, chunk := range chunks {
		part, err := bucket.UploadPart(imur, file, chunk.Size, chunk.Number)
		if err != nil {
			fmt.Printf("Error: %v\n", err)
			return
		}

		fmt.Printf("Part number: %d, ETag: %s\n", chunk.Number, part.ETag)
		parts = append(parts, part)
	}

	// Step 3: Complete the multipart upload.
	_, err = bucket.CompleteMultipartUpload(imur, parts)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}

	fmt.Printf("Completed multipart upload. File size: %d bytes\n", fileSize)
}

Clean up incomplete parts

Important

Due to a policy change to improve compliance and security, starting March 20, 2025, new OSS users must use a custom domain name (CNAME) to perform data API operations on OSS buckets located in Chinese mainland regions. Default public endpoints are restricted for these operations. Refer to the official announcement for a complete list of the affected operations. If you access your data via HTTPS, you must bind a valid SSL Certificate to your custom domain. This is mandatory for OSS Console access, as the console enforces HTTPS.

If a multipart upload is interrupted without being aborted (by calling AbortMultipartUpload), the uploaded parts remain as parts in the bucket and continue to incur storage fees. Clean up these parts promptly to avoid unnecessary storage costs.

Use the console

  1. Go to the Buckets list and click the destination bucket.

  2. In the Objects list, click Parts to view and delete parts.

Use lifecycle rules

Configure lifecycle rules to automatically clean up expired parts. This reduces manual maintenance and prevents omissions. For more information, see Clean up expired parts using lifecycle rules.

Use tools

  • ossbrowser

    On the object list page of the bucket, click Parts to view and delete parts.

  • ossutil

    Use the abort-multipart-upload command to cancel a multipart upload and delete the corresponding part data. The following example shows the command:

    ossutil api abort-multipart-upload --bucket example-bucket --key dest.jpg --upload-id D9F4****************************

Use SDKs

Call the AbortMultipartUpload operation to cancel a multipart upload and delete the corresponding part data. The following sections provide sample code for canceling a multipart upload using common SDKs. For examples in other languages, see the sample code in SDK Reference.

Before running the code, install the appropriate SDK and configure your access credentials as environment variables. If you use a RAM user or RAM role, you must also grant the required permissions. For more information, see API permissions.

Java SDK V2

import com.aliyun.sdk.service.oss2.OSSClient;
import com.aliyun.sdk.service.oss2.credentials.CredentialsProvider;
import com.aliyun.sdk.service.oss2.credentials.StaticCredentialsProvider;
import com.aliyun.sdk.service.oss2.models.AbortMultipartUploadRequest;
import com.aliyun.sdk.service.oss2.models.AbortMultipartUploadResult;

/**
 * Sample for canceling an OSS multipart upload.
 * Shows how to cancel a multipart upload.
 */
public class AbortMultipartUpload {

    public static void main(String[] args) {
        // Obtain access credentials from environment variables.
        String accessKeyId = System.getenv("OSS_ACCESS_KEY_ID");
        String accessKeySecret = System.getenv("OSS_ACCESS_KEY_SECRET");

        // Set the OSS region and endpoint.
        String region = "cn-hangzhou";
        String endpoint = "oss-cn-hangzhou.aliyuncs.com";

        // Configure bucket and file information.
        String bucket = "example-bucket";
        String key = "dest.jpg";
        String uploadId = "D9F4****************************";

        // Create a credential provider.
        CredentialsProvider provider = new StaticCredentialsProvider(accessKeyId, accessKeySecret);

        // Initialize the OSS client.
        OSSClient client = OSSClient.newBuilder()
                .credentialsProvider(provider)
                .region(region)
                .endpoint(endpoint)
                .build();

        try {
            // Cancel the multipart upload.
            AbortMultipartUploadResult result = client.abortMultipartUpload(
                    AbortMultipartUploadRequest.newBuilder()
                            .bucket(bucket)
                            .key(key)
                            .uploadId(uploadId)
                            .build());

            System.out.printf("Canceled multipart upload successfully. Status code: %d, Request ID: %s\n",
                    result.statusCode(), result.requestId());

        } catch (Exception e) {
            System.out.printf("Error: %s\n", e.getMessage());
            e.printStackTrace();
        } finally {
            // Close the client.
            try {
                client.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

Java SDK V1

import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.*;

/**
 * Sample for canceling an OSS multipart upload (V1 SDK).
 * Shows how to cancel a multipart upload.
 */
public class AbortMultipartUpload {

    public static void main(String[] args) {
        // Obtain access credentials from environment variables.
        String accessKeyId = System.getenv("OSS_ACCESS_KEY_ID");
        String accessKeySecret = System.getenv("OSS_ACCESS_KEY_SECRET");

        // Set the OSS region and endpoint.
        String region = "cn-hangzhou";
        String endpoint = "oss-cn-hangzhou.aliyuncs.com";

        // Configure bucket and file information.
        String bucketName = "example-bucket";
        String objectName = "dest.jpg";
        String uploadId = "D9F4****************************";

        // Create a credential provider.
        DefaultCredentialProvider provider = new DefaultCredentialProvider(accessKeyId, accessKeySecret);

        // Configure client parameters.
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);

        // Initialize the OSS client.
        OSS ossClient = OSSClientBuilder.create()
                .credentialsProvider(provider)
                .clientConfiguration(clientBuilderConfiguration)
                .region(region)
                .endpoint(endpoint)
                .build();

        try {
            // Cancel the multipart upload.
            AbortMultipartUploadRequest abortMultipartUploadRequest =
                    new AbortMultipartUploadRequest(bucketName, objectName, uploadId);
            ossClient.abortMultipartUpload(abortMultipartUploadRequest);

            System.out.printf("Canceled multipart upload successfully. Upload ID: %s\n", uploadId);

        } catch (Exception e) {
            System.out.printf("Error: %s\n", e.getMessage());
            e.printStackTrace();
        } finally {
            // Close the client.
            ossClient.shutdown();
        }
    }
}

Python SDK V2

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Sample for canceling a multipart upload using OSS Python SDK V2.
# Cancels a multipart upload and deletes the uploaded parts.

import alibabacloud_oss_v2 as oss

def main():
    # Obtain access credentials from environment variables.
    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    # Load the default configurations of the SDK.
    config = oss.config.load_default()
    config.credentials_provider = credentials_provider

    # Set the OSS region and endpoint.
    config.region = "cn-hangzhou"
    config.endpoint = "oss-cn-hangzhou.aliyuncs.com"

    # Initialize the OSS client.
    client = oss.Client(config)

    # Configure bucket and file information.
    bucket = "example-bucket"
    key = "dest.jpg"
    upload_id = "D9F4****************************"

    # Cancel the multipart upload.
    result = client.abort_multipart_upload(
        oss.AbortMultipartUploadRequest(
            bucket=bucket,
            key=key,
            upload_id=upload_id
        ))

    print(f"Canceled multipart upload successfully. Status code: {result.status_code}, Request ID: {result.request_id}")

if __name__ == "__main__":
    main()

Python SDK V1

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Sample for canceling a multipart upload using OSS Python SDK V1.

import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider

def main():
    # Obtain access credentials from environment variables.
    auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())
    
    # Set the OSS region and endpoint.
    region = "cn-hangzhou"
    endpoint = "https://oss-cn-hangzhou.aliyuncs.com"
    
    # Configure bucket and file information.
    bucket_name = "example-bucket"
    key = "dest.jpg"
    upload_id = "D9F4****************************"
    
    # Initialize the OSS client.
    bucket = oss2.Bucket(auth, endpoint, bucket_name, region=region)
    
    # Cancel the multipart upload.
    bucket.abort_multipart_upload(key, upload_id)
    
    print(f"Canceled multipart upload successfully. Upload ID: {upload_id}")

if __name__ == "__main__":
    main()

Go SDK V2

package main

// Sample for canceling a multipart upload using OSS Go SDK V2.

import (
	"context"
	"fmt"

	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)

func main() {
	// Obtain access credentials from environment variables.
	// Configure the OSS client, set the credential provider and endpoint.
	config := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion("cn-hangzhou").
		WithEndpoint("oss-cn-hangzhou.aliyuncs.com")

	// Initialize the OSS client.
	client := oss.NewClient(config)

	// Configure bucket and file information.
	bucket := "example-bucket"
	key := "dest.jpg"
	uploadId := "D9F4****************************"

	// Cancel the multipart upload.
	client.AbortMultipartUpload(context.TODO(), &oss.AbortMultipartUploadRequest{
		Bucket:   oss.Ptr(bucket),
		Key:      oss.Ptr(key),
		UploadId: oss.Ptr(uploadId),
	})

	fmt.Printf("Canceled multipart upload successfully. Upload ID: %s\n", uploadId)
}

Go SDK V1

package main

// Sample for canceling a multipart upload using OSS Go SDK V1.

import (
	"fmt"

	"github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {
	// Obtain access credentials from environment variables.
	provider, _ := oss.NewEnvironmentVariableCredentialsProvider()

	// Create an OSS client instance.
	client, _ := oss.New(
		"oss-cn-hangzhou.aliyuncs.com",
		"",
		"",
		oss.SetCredentialsProvider(&provider),
		oss.AuthVersion(oss.AuthV4),
		oss.Region("cn-hangzhou"),
	)

	// Obtain the bucket object.
	bucket, _ := client.Bucket("example-bucket")

	// Configure file information.
	key := "dest.jpg"
	uploadId := "D9F4****************************"

	// Create an InitiateMultipartUploadResult object.
	imur := oss.InitiateMultipartUploadResult{
		UploadID: uploadId,
		Key:      key,
	}

	// Cancel the multipart upload.
	bucket.AbortMultipartUpload(imur)

	fmt.Printf("Canceled multipart upload successfully. Upload ID: %s\n", uploadId)
}

Apply in production

Best practices

  • Performance optimization: Improve upload speed and stability

    • Control the number of concurrent parts: Determine a reasonable number of concurrent parts based on your network bandwidth and device load. Too many concurrent connections can increase system load and cause network congestion, while too few cannot fully utilize network resources.

    • Avoid sequential prefixes in names: When you upload many files, avoid using sequential prefixes, such as timestamps, in file names. This prevents requests from being concentrated on a specific partition, which can cause hot spot issues and affect overall upload performance. For more information, see OSS performance best practices.

  • Reliability assurance: Implement resumable uploads

    Multipart uploads do not expire, and they support pause and resume operations. Use the UploadId as the task identifier. If a single part fails to upload, you only need to re-upload that part instead of the entire file from the beginning. This significantly improves transfer efficiency.

  • Cost optimization: Optimize the upload strategy for Deep Cold Archive

    To optimize costs for Deep Cold Archive, first upload files as Standard objects and then use a lifecycle rule to transition them. This avoids the higher per-request PUT fees of direct uploads.

Risk prevention

  • Data security: Prevent file overwrites

    In the upload request header, set the x-oss-forbid-overwrite parameter to true to prevent overwriting files with the same name, which can cause data loss. You can also enable versioning to retain historical versions.

Limits

Limit

Description

Size of a single file

Up to 48.8 TB

Number of parts

1 to 10,000

Size of a single part

The minimum size is 100 KB and the maximum size is 5 GB. The size of the last part can be less than 100 KB.

Maximum number of parts returned in a single ListParts request

1,000

Maximum number of multipart upload events returned in a single ListMultipartUploads request

1,000

Billing

The following table describes the billable items generated by different operations during a multipart upload. For more information about billing, see Request fees and Storage fees.

API

Billable item

Description

InitiateMultipartUpload

PUT requests

Fees are calculated based on the number of successful requests.

UploadPart

PUT requests

Fees are calculated based on the number of successful requests.

Storage fees

Storage fees are charged based on the storage class of the parts (which is the same as the object), their actual size, and the storage duration. There is no minimum unit of measurement. Billing stops after the parts are deleted or combined into a complete object.

UploadPartCopy

PUT requests

Fees are calculated based on the number of successful requests.

CompleteMultipartUpload

PUT requests

Fees are calculated based on the number of successful requests.

Storage fees

Storage fees are charged based on the storage class, size, and duration of the object.

AbortMultipartUpload

PUT requests

Fees are calculated based on the number of successful requests.

Important
  • In the Chinese mainland regions, the PUT request fees for deleting Infrequent Access, Archive, and Cold Archive parts using lifecycle rules are higher than those for deleting Standard parts. No PUT request fees are charged for deleting Deep Cold Archive parts using lifecycle rules.

  • In the Hong Kong (China) region and regions outside China, no PUT request fees are charged for deleting parts of any storage class using lifecycle rules.

ListMultipartUploads

PUT requests

Fees are calculated based on the number of successful requests.

ListParts

PUT requests

Fees are calculated based on the number of successful requests.

API permissions

An Alibaba Cloud account has permissions to call all API operations by default. To use the multipart upload feature as a RAM user or by assuming a RAM role, you must be granted the required permissions for the specific API operations. For more information, see RAM policies and Common examples of RAM policies.

API

Action

Description

InitiateMultipartUpload

oss:PutObject

Initializes a multipart upload.

oss:PutObjectTagging

This permission is required if you specify object tags using x-oss-tagging when you initialize a multipart upload.

kms:GenerateDataKey

These permissions are required if the object metadata contains X-Oss-Server-Side-Encryption: KMS when you upload an object.

kms:Decrypt

UploadPart

oss:PutObject

Uploads a part.

UploadPartCopy

oss:GetObject

Permission to read the source object is required when you upload a part by copying data from an existing object.

oss:PutObject

Permission to write to the destination object is required when you upload a part by copying data from an existing object.

oss:GetObjectVersion

Permission to read the specified version of the source object is required if you specify the object version using versionId when you upload a part by copying data from an existing object.

CompleteMultipartUpload

oss:PutObject

Combines parts into an object.

oss:PutObjectTagging

This permission is required if you specify object tags using x-oss-tagging when you combine parts into an object.

AbortMultipartUpload

oss:AbortMultipartUpload

Cancels a multipart upload event and deletes the corresponding part data.

ListMultipartUploads

oss:ListMultipartUploads

Lists all multipart upload events that are in progress. These are events that have been initiated but not yet completed or aborted.

ListParts

oss:ListParts

Lists all successfully uploaded parts that belong to a specified UploadId.