优先级/严重程度:
对于使用 S3 兼容备份存储的自托管实例,优先级为高,因为归档创建后计划备份会失败。
平台:
最新分支的自托管 Discourse。
观察时的当前运行版本:v2026.4.0-latest
Ruby: 3.4.0
aws-sdk-s3: 1.182.0
描述:
备份到 Cloudflare R2 在最后的“正在上传归档…”步骤失败。
数据库转储和本地归档创建均成功完成,但已完成备份归档的多部分上传失败。
实际结果:
备份失败,错误信息如下:
EXCEPTION: multipart upload failed: undefined method 'downcase' for nil
堆栈跟踪包含:
aws-sdk-s3-1.182.0/lib/aws-sdk-s3/multipart_file_uploader.rb
lib/backup_restore/s3_backup_store.rb:48
lib/backup_restore/creator.rb:434
预期结果:
备份归档应成功上传到配置的 S3 兼容备份存储。
可复现步骤:
- 使用 S3 兼容备份路径将备份存储配置为 Cloudflare R2。
- 使用大于多部分阈值的备份归档。
- 运行手动或计划备份。
- 观察“正在上传归档…”期间发生的失败。
相关配置:
- DISCOURSE_BACKUP_LOCATION=s3
- DISCOURSE_S3_ENDPOINT=https://.r2.cloudflarestorage.com
- DISCOURSE_S3_FORCE_PATH_STYLE=true
- DISCOURSE_S3_BACKUP_BUCKET=
- AWS_REQUEST_CHECKSUM_CALCULATION=WHEN_REQUIRED
- AWS_RESPONSE_CHECKSUM_VALIDATION=WHEN_REQUIRED
观察到的堆栈跟踪片段:
algorithm = resp.context.params[:checksum_algorithm]
k = "checksum_#{algorithm.downcase}".to_sym
这表明在多部分上传路径中,checksum_algorithm 为 nil。
其他背景信息:
Meta 上有一个类似的关于 Backblaze B2 的近期主题:
此外,1.182.0 之后的 aws-sdk-s3 更新日志条目也与此相关:
- 1.201.0:修复多部分上传以在需要时尊重 request_checksum_calculation 模式
- 1.210.2:在使用自定义端点或端点提供程序进行 PutObject 和 UploadPart 操作时,回退到使用头部请求校验和
Discourse 主分支目前似乎仍将 aws-sdk-s3 锁定在 1.182.0:
https://raw.githubusercontent.com/discourse/discourse/main/Gemfile.lock