All Products
Search
Document Center

Object Storage Service:Multipart upload for OSS on CloudBox

Last Updated:Mar 20, 2026

Multipart upload splits an object into parts, uploads them independently, then assembles them into a complete object using CompleteMultipartUpload. Use it for objects larger than 5 GB, unstable network conditions, or when you need to pause and resume an upload.

Use cases

  • Large objects: Objects larger than 5 GB must use multipart upload. Uploading parts in parallel accelerates transfers for large objects.

  • Unstable networks: If a part fails, re-upload only that part—not the entire object—saving time and bandwidth.

  • Pauseable uploads: Multipart upload tasks never expire. Pause and resume at any time before the task completes or is canceled.

  • Unknown object size: When the final size is unknown upfront (for example, live video surveillance streams), multipart upload lets you upload incrementally.

How it works

  1. Call InitiateMultipartUpload to start the task and get an upload ID.

  2. Call UploadPart to upload each part. Parts are identified by part number (1–10,000) and can be uploaded in parallel or out of order—OSS assembles them by part number, not upload sequence.

  3. Call CompleteMultipartUpload to merge the parts into a single object.

To cancel the task and delete all uploaded parts, call AbortMultipartUpload.

Important

Uploaded parts are not deleted automatically. If you never call CompleteMultipartUpload or AbortMultipartUpload, the parts persist in your bucket and consume storage. As a best practice, configure a lifecycle rule to automatically abort incomplete uploads and recover storage. See Delete incomplete uploads.

Prerequisites

Before you begin, ensure that you have:

  • An OSS on CloudBox bucket

Limitations

ItemLimit
Object sizeUp to 48.8 TB
Number of parts1–10,000
Part size100 KB–5 GB (the last part can be less than 100 KB)
Parts returned per ListParts request1,000
Tasks returned per ListMultipartUploads request1,000

Upload an object using multipart upload

Use ossutil (recommended)

For most use cases, ossutil is the simplest option. When you run the cp command on a large local file, ossutil 2.0 automatically applies multipart upload:

ossutil cp D:/localpath/example.iso oss://examplebucket/desfolder/

To run the three-step multipart upload manually, use the initiate-multipart-upload, upload-part, and complete-multipart-upload operations together.

Use the Java SDK

Multipart upload requires Alibaba Cloud SDK for Java version 3.15.0 or later.

The following example uploads a local file in 1 MB parts:

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
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;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.common.auth.CredentialsProviderFactory;
import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider;

public class Demo {

    public static void main(String[] args) throws Exception {
        // Specify the data endpoint of the OSS on CloudBox bucket.
        String endpoint = "https://cb-f8z7yvzgwfkl9q0h****.cn-hangzhou.oss-cloudbox.aliyuncs.com";
        // Obtain access credentials from environment variables.
        // Before running this code, set the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables.
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // Specify the bucket name, for example, examplebucket.
        String bucketName = "examplebucket";
        // Specify the region where the bucket is located.
        String region = "cn-hangzhou";
        // Specify the CloudBox ID.
        String cloudBoxId = "cb-f8z7yvzgwfkl9q0h****";
        // Specify the full object path, for example, exampledir/exampleobject.txt.
        // Do not include the bucket name in the path.
        String objectName = "exampledir/exampleobject.txt";

        // Create an OSSClient instance using Signature V4 and the CloudBox ID.
        // Call shutdown() when the client is no longer needed.
        ClientBuilderConfiguration conf = new ClientBuilderConfiguration();
        conf.setSignatureVersion(SignVersion.V4);
        OSS ossClient = OSSClientBuilder.create()
                .endpoint(endpoint)
                .credentialsProvider(new DefaultCredentialProvider(credentialsProvider.getCredentials()))
                .clientConfiguration(conf)
                .region(region)
                .cloudBoxId(cloudBoxId)
                .build();

        try {
            // Step 1: Initiate the multipart upload and get an upload ID.
            InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(bucketName, objectName);
            InitiateMultipartUploadResult upresult = ossClient.initiateMultipartUpload(request);
            String uploadId = upresult.getUploadId();

            // partETags holds the ETag and part number for each uploaded part.
            List<PartETag> partETags = new ArrayList<PartETag>();
            final long partSize = 1 * 1024 * 1024L; // 1 MB per part

            // Step 2: Upload parts sequentially.
            // Parts can also be uploaded in parallel from multiple clients—OSS assembles them by part number.
            final File sampleFile = new File("D:\\localpath\\examplefile.txt");
            long fileLength = sampleFile.length();
            int partCount = (int) (fileLength / partSize);
            if (fileLength % partSize != 0) {
                partCount++;
            }

            for (int i = 0; i < partCount; i++) {
                long startPos = i * partSize;
                long curPartSize = (i + 1 == partCount) ? (fileLength - startPos) : partSize;
                InputStream instream = new FileInputStream(sampleFile);
                instream.skip(startPos);

                UploadPartRequest uploadPartRequest = new UploadPartRequest();
                uploadPartRequest.setBucketName(bucketName);
                uploadPartRequest.setKey(objectName);
                uploadPartRequest.setUploadId(uploadId);
                uploadPartRequest.setInputStream(instream);
                // Minimum part size is 100 KB, except for the last part.
                uploadPartRequest.setPartSize(curPartSize);
                // Part numbers range from 1 to 10,000. Parts outside this range return InvalidArgument.
                uploadPartRequest.setPartNumber(i + 1);

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

            // Step 3: Complete the upload. OSS verifies each part's ETag before merging.
            CompleteMultipartUploadRequest completeMultipartUploadRequest =
                    new CompleteMultipartUploadRequest(bucketName, objectName, uploadId, partETags);
            CompleteMultipartUploadResult completeMultipartUploadResult =
                    ossClient.completeMultipartUpload(completeMultipartUploadRequest);
            System.out.println(completeMultipartUploadResult.getETag());
        } catch (OSSException oe) {
            System.out.println("OSS rejected the request: " + oe.getErrorMessage());
            System.out.println("Error code: " + oe.getErrorCode());
            System.out.println("Request ID: " + oe.getRequestId());
            System.out.println("Host ID: " + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Client error (network or configuration issue): " + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
}

Use the API directly

All methods above are built on OSS RESTful APIs. Call the APIs directly when you need full control over request construction. Include signature calculation in your code.

OperationDescription
InitiateMultipartUploadStart a multipart upload task
UploadPartUpload a part
UploadPartCopyUpload a part by copying from an existing object
CompleteMultipartUploadMerge parts into a complete object
AbortMultipartUploadCancel the task and delete uploaded parts
ListMultipartUploadsList ongoing multipart upload tasks
ListPartsList uploaded parts for a task

Usage notes

Optimize upload performance

Avoid sequential prefixes (such as timestamps or alphabetical sequences) in object names when uploading many objects. Sequential prefixes concentrate index entries in a single bucket partition, which reduces throughput under high request rates. For guidance, see Best practices for OSS performance.

Prevent accidental overwrites

Uploading an object with the same name as an existing object overwrites it. To prevent accidental overwrites:

  • Enable versioning: Overwritten objects are saved as previous versions and can be restored at any time. See Versioning for OSS on CloudBox.

  • Use the x-oss-forbid-overwrite header: Set x-oss-forbid-overwrite: true in the InitiateMultipartUpload request. If an object with the same name already exists, the upload fails with a FileAlreadyExists error. See InitiateMultipartUpload.

Delete incomplete uploads

When a multipart upload is interrupted, the uploaded parts remain in the bucket and consume storage. As a best practice, configure a lifecycle rule to automatically abort incomplete uploads and recover storage. See Lifecycle rules for OSS on CloudBox.

What's next