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
Call InitiateMultipartUpload to start the task and get an upload ID.
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.
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:
Limitations
| Item | Limit |
|---|
| Object size | Up to 48.8 TB |
| Number of parts | 1–10,000 |
| Part size | 100 KB–5 GB (the last part can be less than 100 KB) |
| Parts returned per ListParts request | 1,000 |
| Tasks returned per ListMultipartUploads request | 1,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.
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.