You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Cloudflare R2中CompleteMultipartUploadCommand持续返回500错误求助

Cloudflare R2分片上传完成阶段500错误解决指南

问题概述

已配置Cloudflare R2存储桶CORS规则,严格遵循教程完成分片上传初始化及分片上传步骤(均返回成功),但执行完成分片上传操作时返回500错误。

初始化分片上传响应

{"msg":"Success: /getMultiPartUpload","response":{"$metadata": {"httpStatusCode":200,"attempts":1,"totalRetryDelay":0},"AbortDate":"2024-09-05T21:01:52.000Z","AbortRuleId":"Default%20Multipart%20Abort%20Rule","Bucket":"haluv-post-video","Key":"bucket-name","UploadId":"AFeJAbAoJRPjhzMYM"}}

分片上传返回的ETag示例

..."ETag":"\"dfbf2996205d747c40ab5cc43a94300e\""}}
..."ETag":"\"ff3b8f9d875e5f0bced05c50bb9181ab\""}}
..."ETag":"\"a0f1e95938135f7118e32e8a44820813\""}}
..."ETag":"\"e0e174e3ba4157de8d66b080d7a09d41\""}}

完成分片上传代码

async function completeMultipartUpload(S3, request, headers) {

try {
    const url = new URL(request.url);
    const params = url.searchParams;
    const bucket = params.get('bucket');
    const key = params.get('key');
    const uploadId = params.get('uploadId');

    const partsData = await request.json();
    const parts = partsData.parts;

    const input = {
        "Bucket": bucket,
        "Key": key,
        "MultipartUpload": {
            "Parts": parts
        },
        "UploadId": uploadId
    }

    const command = new CompleteMultipartUploadCommand(input); // 错误发生位置
    const response = await S3.send(command);

    return new Response(JSON.stringify({
        msg: '/completeMultipartUpload',
        response: response
    }), {
        status: 200,
        headers: headers
    });
} catch (err) {
    return new Response(JSON.stringify({
        msg: 'Error: /completeMultipartUpload',
        error: JSON.stringify(err)
    }), {
        status: 500,
        headers: headers
    });
}
}

错误信息(已翻译)

DioException [bad response]:抛出此异常是因为响应状态码为500,且RequestOptions.validateStatus配置为此状态码时抛出异常。


排查与修复步骤

1. 修正分片ETag格式

从提供的ETag来看,每个值都包含外层双引号,但Cloudflare R2要求ETag参数必须去掉首尾双引号。修改代码中组装Parts的逻辑:

const parts = partsData.parts.map(part => ({
    ETag: part.ETag.replace(/^"|"$/g, ''), // 移除首尾双引号
    PartNumber: part.PartNumber
}));

2. 验证分片数组完整性

确保Parts数组中的每个元素都包含:

  • PartNumber:从1开始的连续整数,与分片上传时的序号完全一致
  • ETag:修正格式后的哈希字符串
    分片序号不能缺失或重复,否则会触发R2内部错误。

3. 核对核心参数一致性

确认请求中的bucket、key、uploadId与初始化分片上传时返回的参数完全匹配,尤其是Key值(示例中初始化响应的Key为bucket-name,需确保完成请求时Key一致)。

4. 获取详细错误日志

修改catch块,输出更详细的错误信息,便于定位根本原因:

catch (err) {
    console.error('Complete upload failure:', err); // 控制台打印完整错误
    return new Response(JSON.stringify({
        msg: 'Error: /completeMultipartUpload',
        errorMessage: err.message,
        requestMetadata: err.$metadata || {} // AWS SDK错误包含元数据
    }), {
        status: 500,
        headers: headers
    });
}

通过详细错误信息可直接知道R2拒绝请求的具体原因(如分片缺失、ETag不匹配等)。

5. 检查Worker权限配置

确保执行该操作的Worker拥有以下R2权限:

  • r2:PutObject
  • r2:CompleteMultipartUpload
    权限不足会导致R2返回内部错误。

内容的提问来源于stack exchange,提问作者ryandra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 20:35:18