Cloudflare R2 へのバックアップが aws-sdk-s3 1.182.0 でのマルチパートアップロード中に失敗(nil の undefined method 'downcase')

優先度/重大度:

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 互換のバックアップストアへ正常にアップロードされるべきです。

再現手順:

  1. S3 互換のバックアップパスを使用して、バックアップストレージを Cloudflare R2 として設定する。
  2. マルチパート閾値を超えるサイズのバックアップアーカイブを使用する。
  3. 手動またはスケジュールされたバックアップを実行する。
  4. 「アーカイブのアップロード中…」の段階で失敗を観測する。

関連設定:

  • 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 であることを示唆しています。

追加のコンテキスト:

Backblaze B2 に関する類似の最近の Meta トピックがあります:

また、1.182.0 以降の aws-sdk-s3 の変更ログ項目も関連しているようです:

  • 1.201.0: request_checksum_calculationwhen_required モードの場合、マルチパートアップロードがそれを尊重するように修正
  • 1.210.2: PutObject および UploadPart 操作でカスタムエンドポイントまたはエンドポイントプロバイダーを使用する際に、ヘッダーリクエストチェックサムにフォールバック

Discourse main 現在は依然として aws-sdk-s3 を 1.182.0 にロックしているようです:

https://raw.githubusercontent.com/discourse/discourse/main/Gemfile.lock