All Products
Search
Document Center

Object Storage Service:Multipart upload

Last Updated:Dec 16, 2025

Uploading large files can be challenging because of potential network interruptions and long transfer times. Multipart upload addresses these issues by splitting a file into smaller parts that are uploaded concurrently. This method supports resumable uploads and improves transfer performance, making it effective for file transfers in unstable network environments.

How it works

Multipart upload splits a large file into multiple smaller parts that are processed independently. Each part is uploaded and verified separately. If a part fails to upload, you only need to re-upload that specific part instead of the entire file. Multipart upload uses an Upload ID to identify the task and ensure that all parts are correctly associated with the same upload. The core process consists of three steps:

  1. Initialize the upload task: Call the InitiateMultipartUpload API to create a multipart upload task and obtain a unique Upload ID to identify the task in subsequent operations.

  2. Upload parts: You can split the file into multiple parts and upload them concurrently. The size of each part can range from 100 KB to 5 GB. This step supports resumable uploads.

  3. Complete the upload: Call the CompleteMultipartUpload API to merge all uploaded parts in order by part number to create a complete object.

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.

You can use graphical tools, command-line tools, or software development kits (SDKs) to implement multipart upload, depending on your application scenario and technical requirements.

Note
  • The OSS console does not support multipart upload operations.

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

Automatic part splitting with tools

For daily development, testing, operations and maintenance (O&M), or manual upload scenarios, we recommend that you use graphical or command-line tools. These tools automatically handle the part splitting logic and are easy to use.

Programmatic part splitting with SDKs

SDKs for various languages provide complete encapsulation for multipart upload APIs and support custom part sizes, concurrency control, and error handling. The following are examples of multipart upload that use SDKs for common languages. For code samples in other languages, see the examples for the corresponding language in SDK Reference.

Before you run the code, you must install the SDK for the corresponding language and configure environment variables for your access credentials. If you use a Resource Access Management (RAM) user or RAM role, you must also grant the required permissions for the API operations. For more information, see API and permission reference.

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;

/**
 * OSS multipart upload example
 * 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("Multipart upload initialized 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 the 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("Multipart upload completed. 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 connection.
            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;

/**
 * OSS multipart upload example (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("Multipart upload initialized 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 the 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 a part upload request.
                UploadPartRequest uploadPartRequest = new UploadPartRequest();
                uploadPartRequest.setBucketName(bucketName);
                uploadPartRequest.setKey(objectName);
                uploadPartRequest.setUploadId(uploadId);
                uploadPartRequest.setPartNumber(i + 1);
                uploadPartRequest.setPartSize(curPartSize);

                // Read the 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("Part %d/%d uploaded 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("Multipart upload completed. ETag: %s\n", completeResult.getETag());

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

Python SDK V2

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

# OSS Python SDK V2 multipart upload example
# 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 SDK configuration.
    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"Multipart upload initialized 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 current part size.
                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"Multipart upload completed. 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 -*-

# OSS Python SDK V1 multipart upload example
# 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"Multipart upload initialized 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 current part size.
                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"Multipart upload completed. ETag: {result.etag}")

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

if __name__ == "__main__":
    main()

Go SDK V2

package main

// OSS Go SDK V2 multipart upload example
// 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("Multipart upload initialized 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 current part size.
		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("Multipart upload completed. Bucket: %s, Key: %s, Location: %s, ETag: %s\n",
		*completeResult.Bucket, *completeResult.Key, *completeResult.Location, *completeResult.ETag)
}

Go SDK V1

package main

// OSS Go SDK V1 multipart upload example
// 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"),
	)

	// Get 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("Multipart upload initialized 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("Multipart upload completed. File size: %d bytes\n", fileSize)
}

Clean up fragment 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.

If a multipart upload is interrupted unexpectedly and the AbortMultipartUpload API is not called, the uploaded parts are retained in the bucket as fragments and will continue to incur storage costs. You must promptly clean up these fragments to avoid unnecessary storage costs.

Using the console

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

  2. In the Files list, click Fragment Management to view and delete fragments.

Using lifecycle rules

You can configure a lifecycle rule to automatically clean up expired parts. This method reduces manual maintenance and prevents parts from being missed. For more information, see Clean up expired parts using a lifecycle rule.

Using tools

  • ossbrowser, a graphical management tool

    In the file list of the bucket, click File Fragments to view and delete fragments.

  • ossutil, a command-line tool

    You can use the abort-multipart-upload command to cancel a multipart upload task and delete the uploaded parts. The following is a sample command:

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

Using SDKs

You can call the AbortMultipartUpload API to cancel a multipart upload task and delete the uploaded parts. The following sections provide code samples that show how to cancel a multipart upload task using SDKs for common languages. For code samples in other languages, see the examples for the corresponding language in SDK Reference.

Before you run the code, you must install the SDK for the corresponding language and configure environment variables for your access credentials. If you use a RAM user or RAM role, you must also grant the required permissions for the API operations. For more information, see API and permission reference.

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;

/**
 * OSS cancel multipart upload example
 * Demonstrates how to cancel a multipart upload task.
 */
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("Multipart upload canceled 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 connection.
            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.*;

/**
 * OSS cancel multipart upload example (V1 SDK)
 * Demonstrates how to cancel a multipart upload task.
 */
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("Multipart upload canceled successfully. Upload ID: %s\n", uploadId);

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

Python SDK V2

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

# OSS Python SDK V2 cancel multipart upload example
# Cancels a multipart upload task 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 SDK configuration.
    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"Multipart upload canceled 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 -*-

# OSS Python SDK V1 cancel multipart upload example

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"Multipart upload canceled successfully. Upload ID: {upload_id}")

if __name__ == "__main__":
    main()

Go SDK V2

package main

// OSS Go SDK V2 cancel multipart upload example

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("Multipart upload canceled successfully. Upload ID: %s\n", uploadId)
}

Go SDK V1

package main

// OSS Go SDK V1 cancel multipart upload example

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"),
	)

	// Get 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("Multipart upload canceled successfully. Upload ID: %s\n", uploadId)
}

Going live

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 the system load and cause network congestion, while too few may not make full use of your network resources.

    • Avoid sequential prefixes in object names: When you upload many files, avoid using sequential prefixes, such as timestamp-based prefixes, for object names. This practice prevents requests from being concentrated on a specific partition, which can cause hot spots and affect the overall upload performance. For more information, see Best practices for OSS performance.

  • Ensure reliability: Implement resumable uploads

    Multipart upload tasks do not expire and support pause and resume operations. You can use the Upload ID to identify the task. If a part fails to upload, you need to re-upload only that part. This way, you do not need to upload the entire file from the beginning, which significantly improves transfer efficiency.

  • Optimize costs: Refine the upload strategy for Deep Cold Archive

    To store many files in the Deep Cold Archive storage class, we recommend that you first upload them to the Standard storage class. Then, you can use a lifecycle rule to automatically transition the files to Deep Cold Archive. This strategy helps you avoid the high PUT request fees that are associated with direct uploads to Deep Cold Archive.

Risk prevention

  • Data security: Prevent object overwrites

    You can set the x-oss-forbid-overwrite parameter to true in the upload request header to prevent existing objects with the same name from being overwritten. This helps prevent accidental data loss. Alternatively, you can enable the versioning feature to retain historical versions of objects.

Quotas and 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 size can range from 100 KB to 5 GB. The size of the last part can be less than 100 KB.

Maximum number of parts returned by a single ListParts request

1,000

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

1,000

Billing

The following table lists the billable items that are generated by different API operations during the multipart upload process. For more information about billing, see Request fees and Storage fees.

API

Billable item

Description

InitiateMultipartUpload

PUT-like requests

Request fees are calculated based on the number of successful requests.

UploadPart

PUT-like requests

Request 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 storage duration. There is no minimum unit of measurement. Billing stops after the parts are deleted or merged into a complete object file.

UploadPartCopy

PUT-like requests

Request fees are calculated based on the number of successful requests.

CompleteMultipartUpload

PUT-like requests

Request 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 file.

AbortMultipartUpload

PUT-like requests

Request fees are calculated based on the number of successful requests.

Important
  • In regions in the Chinese mainland, 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-like requests

Request fees are calculated based on the number of successful requests.

ListParts

PUT-like requests

Request fees are calculated based on the number of successful requests.

API and permission reference

By default, an Alibaba Cloud account has permissions to call all API operations. If you use a RAM user or RAM role to perform multipart uploads, you must grant the required permissions for the API operations. For more information, see RAM policies and Common examples of RAM policies.

API

Action

Description

InitiateMultipartUpload

oss:PutObject

Initiates a multipart upload task.

oss:PutObjectTagging

This permission is required if you specify object tags using x-oss-tagging when you initiate the multipart upload task.

kms:GenerateDataKey

These permissions are required if the object metadata includes 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

Merges parts into an object file.

oss:PutObjectTagging

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

AbortMultipartUpload

oss:AbortMultipartUpload

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

ListMultipartUploads

oss:ListMultipartUploads

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

ListParts

oss:ListParts

Lists all successfully uploaded parts that belong to a specified Upload ID.