跳转到主要内容

BadDigest、InvalidRequest 与 CompleteMultipartUpload 校验和契约

2026-09-17 发布更新: 流式校验和后续修复(PR #143)已随 Server 20260916 发布;协调升级、可选功能启用条件和剩余限制仍按各节执行。下方带日期的源码状态与验证记录保留当时的范围。

#48#50 的修复 已包含在 Server 20260903 中。 本文取代八月提案中“暂时保持 CRC64NVME 规范化”的结论。

为什么必须在完成时校验

初始化上传时选择算法和对象校验和类型,各分片保存其校验和值。 完成请求必须依据已存储的契约校验最终值与显式类型断言,不能因为基础算法相同就将 COMPOSITE 改为 FULL_OBJECT, 也不能通过省略最终摘要绕过类型断言。

修复区分省略类型与显式类型,只规范化内部表示标志,并采用操作专用错误类型,保持 UploadPart 与全局校验和错误映射不变。

当前错误契约

下列失败均返回 HTTP 400,不会提交新的已完成对象。

请求条件 S3 错误
整对象或组合对象摘要错误 BadDigest
显式有效类型与初始化类型不同,包括仅提供类型的断言 BadDigest
未知或小写类型 token InvalidArgument
完成时算法不同于初始化算法 InvalidArgument
缺少组合校验和所需的分片值 InvalidRequest,指出算法与分片
初始化时 CRC64NVME 配合 COMPOSITE InvalidArgument
完成时 CRC64NVME 值与 COMPOSITE 在解析阶段被拒绝 InvalidArgument
CRC64NVME FULL_OBJECT 上传在完成时仅断言 COMPOSITE BadDigest
UploadPart 的客户端校验和错误 保留 XAmzContentChecksumMismatch

FULL_OBJECT 可以省略分片校验和,但仍校验已提供的值。允许匹配的仅类型断言。 省略可选类型不等于断言 COMPOSITE。SHA1/SHA256 配合 FULL_OBJECT 会在算法/类型解析阶段被拒绝,不会进入存储类型比较。

CRC64NVME 决策与源码证据

最初评审因等待证据而推迟 #50,这是历史决策,不是当前契约。 PR #93 在 header 与 trailer 路径拒绝非法算法/类型组合, PR #96 则移除完成阶段的规范化,两者都早于 20260903 tag。 完成请求可在解析阶段或存储类型比较阶段失败,因此存在上表中两种不同错误码。

最初错误映射位于 PR #74,显式类型后续修复 7e079ff05PR #85 合入。 当前处理器测试 覆盖整对象与组合不匹配、仅类型断言、非法 token 及 CRC64NVME 两个拒绝阶段。 这是已提交的回归覆盖,不表示本次文档修改重新运行了所有 Server 测试。

独立的流式校验和后续修复

PR #143 跟进 @cbornet 报告的 #107,处理 AWS Java SDK v2 使用的路径:aws-chunked 请求通过 x-amz-trailer 声明校验和,却在 header 中提供其值。它也拒绝非法的 header 校验和值,避免丢弃校验。 此后续修复已在 main,不在 Server 20260903 中,与完成错误映射是独立变化。

兼容性与剩余边界

检查错误码的客户端会看到摘要或类型失败变为 BadDigest,缺少组合分片值变为 InvalidRequest。 成功的无校验和上传与 ETag 语义不变,无需迁移元数据。

仍有较窄的差异:初始化未记录校验和却在完成时提供最终摘要,会返回 BadDigest;组合分片数与值不匹配使用相同描述; 整对象校验和的 -N 后缀本身不作为分片数验证。这些是已记录的观察,不表示已分别建立公开 issue,也不代表完整 AWS 一致性。