All Products
Search
Document Center

Object Storage Service:Multipart upload (C++ SDK)

Last Updated:Mar 20, 2026

Multipart upload splits a large object into smaller parts, uploads each part independently, and combines them into a single object by calling CompleteMultipartUpload. Use multipart upload for large objects to get:

  • Resumable uploads — resume an interrupted upload without restarting from scratch

  • Fault tolerance — a network error only affects the current part, not the entire upload

Prerequisites

Before you begin, ensure that you have:

  • The oss:PutObject permission (required for InitiateMultipartUpload, UploadPart, and CompleteMultipartUpload)

  • The OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables set with valid credentials

  • The OSS C++ SDK installed and initialized

For endpoint configuration and OSSClient setup options, see Regions and endpoints and Create an OSSClient instance.

How it works

A multipart upload consists of three steps:

  1. Initiate — call InitiateMultipartUpload to get a globally unique upload ID from OSS.

  2. Upload parts — call UploadPart for each part, using the upload ID to associate parts with the same upload.

  3. Complete — call CompleteMultipartUpload with the ETag of every uploaded part. OSS verifies each part and assembles the final object.

Part constraints:

ConstraintValue
Minimum part size100 KB
Maximum part size5 GB
Last part minimum sizeNo minimum (can be less than 100 KB)

Part numbering: if you upload new data using the same part number, OSS overwrites the existing part data for that number.

Data integrity: OSS computes the MD5 hash of each received part and returns it in the response ETag header. The SDK computes its own MD5 hash and compares it with OSS's value. A mismatch returns the InvalidDigest error code.

Upload a large object

The following example shows a complete multipart upload that reads a local file, splits it into 100 KB parts, and uploads each part sequentially.

All examples use SignatureVersionType::V4 and load credentials from environment variables.

#include <alibabacloud/oss/OssClient.h>
#include <fstream>

// Returns the size of a local file in bytes.
int64_t getFileSize(const std::string& file)
{
    std::fstream f(file, std::ios::in | std::ios::binary);
    f.seekg(0, f.end);
    int64_t size = f.tellg();
    f.close();
    return size;
}

using namespace AlibabaCloud::OSS;

int main(void)
{
    // Replace the placeholders below with your actual values.
    // Endpoint example: https://oss-cn-hangzhou.aliyuncs.com (China (Hangzhou) public endpoint)
    std::string Endpoint = "yourEndpoint";
    // Region example: cn-hangzhou
    std::string Region = "yourRegion";
    std::string BucketName = "examplebucket";
    // Full object path, excluding the bucket name. Example: exampledir/exampleobject.txt
    std::string ObjectName = "exampledir/exampleobject.txt";

    // Initialize network resources.
    InitializeSdk();

    ClientConfiguration conf;
    conf.signatureVersion = SignatureVersionType::V4;
    // Load credentials from OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables.
    auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
    OssClient client(Endpoint, credentialsProvider, conf);
    client.SetRegion(Region);

    // Step 1: Initiate the multipart upload to get an upload ID.
    InitiateMultipartUploadRequest initUploadRequest(BucketName, ObjectName);
    // (Optional) Set the storage class:
    // initUploadRequest.MetaData().addHeader("x-oss-storage-class", "Standard");
    auto uploadIdResult = client.InitiateMultipartUpload(initUploadRequest);
    auto uploadId = uploadIdResult.result().UploadId();
    // Save the upload ID if you need to cancel the upload or list uploaded parts later.

    // Step 2: Upload each part.
    // Part size: minimum 100 KB, maximum 5 GB. The last part can be smaller than 100 KB.
    std::string fileToUpload = "yourLocalFilename";
    int64_t partSize = 100 * 1024;
    PartList partETagList;
    auto fileSize = getFileSize(fileToUpload);
    int partCount = static_cast<int>(fileSize / partSize);
    if (fileSize % partSize != 0) {
        partCount++;
    }

    for (int i = 1; i <= partCount; i++) {
        auto skipBytes = partSize * (i - 1);
        auto size = (partSize < fileSize - skipBytes) ? partSize : (fileSize - skipBytes);
        std::shared_ptr<std::iostream> content =
            std::make_shared<std::fstream>(fileToUpload, std::ios::in | std::ios::binary);
        content->seekg(skipBytes, std::ios::beg);

        UploadPartRequest uploadPartRequest(BucketName, ObjectName, content);
        uploadPartRequest.setContentLength(size);
        uploadPartRequest.setUploadId(uploadId);
        uploadPartRequest.setPartNumber(i);
        auto uploadPartOutcome = client.UploadPart(uploadPartRequest);

        if (uploadPartOutcome.isSuccess()) {
            // Save the ETag returned for each part — required to complete the upload.
            Part part(i, uploadPartOutcome.result().ETag());
            partETagList.push_back(part);
        } else {
            std::cout << "UploadPart fail"
                      << ", code:" << uploadPartOutcome.error().Code()
                      << ", message:" << uploadPartOutcome.error().Message()
                      << ", requestId:" << uploadPartOutcome.error().RequestId() << std::endl;
        }
    }

    // Step 3: Complete the multipart upload.
    // Provide all part ETags. OSS verifies each part and assembles the final object.
    CompleteMultipartUploadRequest request(BucketName, ObjectName);
    request.setUploadId(uploadId);
    request.setPartList(partETagList);
    // (Optional) Set the access control list (ACL):
    // request.setAcl(CannedAccessControlList::Private);

    auto outcome = client.CompleteMultipartUpload(request);
    if (!outcome.isSuccess()) {
        std::cout << "CompleteMultipartUpload fail"
                  << ", code:" << outcome.error().Code()
                  << ", message:" << outcome.error().Message()
                  << ", requestId:" << outcome.error().RequestId() << std::endl;
        return -1;
    }

    // Release network resources.
    ShutdownSdk();
    return 0;
}

Getting part ETags: CompleteMultipartUpload requires the ETag of every uploaded part. Get ETags in one of two ways:

  • From the upload response — the code above saves the ETag from each UploadPart response.

  • By calling ListParts — query all uploaded parts for a given upload ID.

List uploaded parts

Call ListParts to list all successfully uploaded parts for a given upload ID. By default, up to 1,000 parts are returned per request. If your upload has more than 1,000 parts, retrieve them by page.

List parts (default limit)

#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    std::string Endpoint = "yourEndpoint";
    std::string Region = "yourRegion";
    std::string BucketName = "examplebucket";
    std::string ObjectName = "exampledir/exampleobject.txt";
    // Upload ID obtained from InitiateMultipartUpload.
    std::string UploadId = "yourUploadId";

    InitializeSdk();

    ClientConfiguration conf;
    conf.signatureVersion = SignatureVersionType::V4;
    auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
    OssClient client(Endpoint, credentialsProvider, conf);
    client.SetRegion(Region);

    // List up to 1,000 uploaded parts (default).
    ListPartsRequest listuploadrequest(BucketName, ObjectName);
    listuploadrequest.setUploadId(UploadId);

    bool IsTruncated = false;
    do {
        auto listUploadResult = client.ListParts(listuploadrequest);
        if (!listUploadResult.isSuccess()) {
            std::cout << "ListParts fail"
                      << ", code:" << listUploadResult.error().Code()
                      << ", message:" << listUploadResult.error().Message()
                      << ", requestId:" << listUploadResult.error().RequestId() << std::endl;
            break;
        }
        for (const auto& part : listUploadResult.result().PartList()) {
            std::cout << "part"
                      << ", name:" << part.PartNumber()
                      << ", size:" << part.Size()
                      << ", etag:" << part.ETag()
                      << ", lastmodify time:" << part.LastModified() << std::endl;
        }
        listuploadrequest.setPartNumberMarker(listUploadResult.result().NextPartNumberMarker());
        IsTruncated = listUploadResult.result().IsTruncated();
    } while (IsTruncated);

    ShutdownSdk();
    return 0;
}

List parts by page

To control page size, set setMaxParts() and use NextPartNumberMarker to fetch the next page.

#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    std::string Endpoint = "yourEndpoint";
    std::string Region = "yourRegion";
    std::string BucketName = "examplebucket";
    std::string ObjectName = "exampledir/exampleobject.txt";
    std::string UploadId = "yourUploadId";

    InitializeSdk();

    ClientConfiguration conf;
    conf.signatureVersion = SignatureVersionType::V4;
    auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
    OssClient client(Endpoint, credentialsProvider, conf);
    client.SetRegion(Region);

    ListPartsRequest listuploadrequest(BucketName, ObjectName);
    listuploadrequest.setUploadId(UploadId);
    listuploadrequest.setMaxParts(50);  // Return 50 parts per page.

    bool IsTruncated = false;
    do {
        auto listuploadresult = client.ListParts(listuploadrequest);
        if (!listuploadresult.isSuccess()) {
            std::cout << "ListParts fail"
                      << ", code:" << listuploadresult.error().Code()
                      << ", message:" << listuploadresult.error().Message()
                      << ", requestId:" << listuploadresult.error().RequestId() << std::endl;
            break;
        }
        for (const auto& part : listuploadresult.result().PartList()) {
            std::cout << "part"
                      << ", name:" << part.PartNumber()
                      << ", size:" << part.Size()
                      << ", etag:" << part.ETag()
                      << ", lastmodify time:" << part.LastModified() << std::endl;
        }
        listuploadrequest.setPartNumberMarker(listuploadresult.result().NextPartNumberMarker());
        IsTruncated = listuploadresult.result().IsTruncated();
    } while (IsTruncated);

    ShutdownSdk();
    return 0;
}

List multipart upload events

Call ListMultipartUploads to list all in-progress multipart upload events — those that have been initiated but not yet completed or canceled. By default, up to 1,000 events are returned per request.

List upload events (default limit)

#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    std::string Endpoint = "yourEndpoint";
    std::string Region = "yourRegion";
    std::string BucketName = "examplebucket";

    InitializeSdk();

    ClientConfiguration conf;
    conf.signatureVersion = SignatureVersionType::V4;
    auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
    OssClient client(Endpoint, credentialsProvider, conf);
    client.SetRegion(Region);

    // List up to 1,000 in-progress upload events (default).
    ListMultipartUploadsRequest listmultiuploadrequest(BucketName);
    bool IsTruncated = false;
    do {
        auto listresult = client.ListMultipartUploads(listmultiuploadrequest);
        if (!listresult.isSuccess()) {
            std::cout << "ListMultipartUploads fail"
                      << ", code:" << listresult.error().Code()
                      << ", message:" << listresult.error().Message()
                      << ", requestId:" << listresult.error().RequestId() << std::endl;
            break;
        }
        for (const auto& part : listresult.result().MultipartUploadList()) {
            std::cout << "part"
                      << ", name:" << part.Key
                      << ", uploadid:" << part.UploadId
                      << ", initiated time:" << part.Initiated << std::endl;
        }
        listmultiuploadrequest.setKeyMarker(listresult.result().NextKeyMarker());
        listmultiuploadrequest.setUploadIdMarker(listresult.result().NextUploadIdMarker());
        IsTruncated = listresult.result().IsTruncated();
    } while (IsTruncated);

    ShutdownSdk();
    return 0;
}

List upload events by page

To control page size, set setMaxUploads() and use NextKeyMarker and NextUploadIdMarker to fetch the next page.

#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    std::string Endpoint = "yourEndpoint";
    std::string Region = "yourRegion";
    std::string BucketName = "examplebucket";

    InitializeSdk();

    ClientConfiguration conf;
    conf.signatureVersion = SignatureVersionType::V4;
    auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
    OssClient client(Endpoint, credentialsProvider, conf);
    client.SetRegion(Region);

    ListMultipartUploadsRequest listmultiuploadrequest(BucketName);
    listmultiuploadrequest.setMaxUploads(50);  // Return 50 events per page.

    bool IsTruncated = false;
    do {
        auto listresult = client.ListMultipartUploads(listmultiuploadrequest);
        if (!listresult.isSuccess()) {
            std::cout << "ListMultipartUploads fail"
                      << ", code:" << listresult.error().Code()
                      << ", message:" << listresult.error().Message()
                      << ", requestId:" << listresult.error().RequestId() << std::endl;
            break;
        }
        for (const auto& part : listresult.result().MultipartUploadList()) {
            std::cout << "part"
                      << ", name:" << part.Key
                      << ", uploadid:" << part.UploadId
                      << ", initiated time:" << part.Initiated << std::endl;
        }
        listmultiuploadrequest.setKeyMarker(listresult.result().NextKeyMarker());
        listmultiuploadrequest.setUploadIdMarker(listresult.result().NextUploadIdMarker());
        IsTruncated = listresult.result().IsTruncated();
    } while (IsTruncated);

    ShutdownSdk();
    return 0;
}

Cancel a multipart upload

Call AbortMultipartUpload to cancel an in-progress upload. After cancellation, the upload ID becomes invalid and all uploaded parts are deleted.

#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    std::string Endpoint = "yourEndpoint";
    std::string Region = "yourRegion";
    std::string BucketName = "examplebucket";
    std::string ObjectName = "exampledir/exampleobject.txt";
    // Upload ID obtained from InitiateMultipartUpload.
    std::string UploadId = "yourUploadId";

    InitializeSdk();

    ClientConfiguration conf;
    conf.signatureVersion = SignatureVersionType::V4;
    auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
    OssClient client(Endpoint, credentialsProvider, conf);
    client.SetRegion(Region);

    // Initiate a multipart upload to get an upload ID (if you don't already have one).
    InitiateMultipartUploadRequest initUploadRequest(BucketName, ObjectName);
    auto uploadIdResult = client.InitiateMultipartUpload(initUploadRequest);
    auto uploadId = uploadIdResult.result().UploadId();

    // Cancel the multipart upload. All uploaded parts are deleted.
    AbortMultipartUploadRequest abortUploadRequest(BucketName, ObjectName, uploadId);
    auto outcome = client.AbortMultipartUpload(abortUploadRequest);

    if (!outcome.isSuccess()) {
        std::cout << "AbortMultipartUpload fail"
                  << ", code:" << outcome.error().Code()
                  << ", message:" << outcome.error().Message()
                  << ", requestId:" << outcome.error().RequestId() << std::endl;
        return -1;
    }

    ShutdownSdk();
    return 0;
}

References