# 초기화되지 않은 TransferManager로 인한 백업 업로드 실패

**URL:** https://meta.discourse.org/t/backup-upload-failure-due-to-uninitialized-transfermanager/409303
**Category:** Self-hosting
**Created:** [8월 4, 2026, 6:09오후 UTC](https://meta.discourse.org/t/backup-upload-failure-due-to-uninitialized-transfermanager/409303 "2026-08-04T18:09:06Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![exodrifter](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/exodrifter/32/506103_2.png) [@exodrifter](https://meta.discourse.org/u/exodrifter)
#### Post date: [8월 4, 2026, 6:09오후 UTC](https://meta.discourse.org/t/backup-upload-failure-due-to-uninitialized-transfermanager/409303/1 "2026-08-04T18:09:07Z")

</div>

[v2026.8.0-latest.1 +4](https://github.com/discourse/discourse/commit/7f9005681164a9247a96a4a009c17e3902696177)로 업데이트한 후 내 백업이 실패하기 시작했습니다. 로그는 다음과 같습니다: [log.txt.zip](https://meta.discourse.org/uploads/short-url/vnqFEpOqapTQiGgzgw1dd1gwEjJ.zip) (22.1 KB)

특히, 다음 부분이 관련 있어 보입니다:

```plaintext
[2026-08-04 03:37:52] Uploading archive...
[2026-08-04 03:37:52] EXCEPTION: uninitialized constant Aws::S3::TransferManager
[2026-08-04 03:37:52] /var/www/discourse/lib/s3_helper.rb:453:in 'S3Helper#transfer_manager'
/var/www/discourse/lib/s3_helper.rb:332:in 'S3Helper#upload_file'
/var/www/discourse/lib/backup_restore/s3_backup_store.rb:48:in 'BackupRestore::S3BackupStore#upload_file'
/var/www/discourse/lib/backup_restore/creator.rb:437:in 'BackupRestore::Creator#upload_archive'
/var/www/discourse/lib/backup_restore/creator.rb:41:in 'BackupRestore::Creator#run'
/var/www/discourse/lib/backup_restore.rb:13:in 'BackupRestore.backup!'
/var/www/discourse/app/jobs/regular/create_backup.rb:10:in 'Jobs::CreateBackup#execute'
/var/www/discourse/app/jobs/base.rb:313:in 'block (2 levels) in Jobs::Base#perform'

```

이 문제를 어떻게 해결해야 할지 모르겠습니다.

---

<div class="post-metadata">

### Author: ![exodrifter](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/exodrifter/32/506103_2.png) [@exodrifter](https://meta.discourse.org/u/exodrifter)
#### Post date: [9월 14, 2026, 12:07오전 UTC](https://meta.discourse.org/t/backup-upload-failure-due-to-uninitialized-transfermanager/409303/2 "2026-09-14T00:07:58Z")

</div>

[v2026.9.0-latest +565](https://github.com/discourse/discourse/commit/9cccc5837dc83a7af376dd40d4cb709cd25b0228 "9cccc5837dc83a7af376dd40d4cb709cd25b0228")로 업데이트했지만, 여전히 동일한 문제가 발생합니다.

---

<div class="post-metadata">

### Author: ![olivia](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/olivia/32/324299_2.png) [@olivia](https://meta.discourse.org/u/olivia)
#### Post date: [9월 14, 2026, 4:40오전 UTC](https://meta.discourse.org/t/backup-upload-failure-due-to-uninitialized-transfermanager/409303/3 "2026-09-14T04:40:38Z")

</div>

사용 중인 Discourse 버전에는 `Aws::S3::TransferManager`를 제공해야 하는 `aws-sdk-s3` 버전이 포함되어 있습니다.

공식 Discourse Docker 설치 방식을 사용 중인가요? 공식 Docker 설정을 사용 중인 경우, 업그레이드 과정에서 컨테이너가 완전히 다시 빌드되었나요?

---

<div class="post-metadata">

### Author: ![exodrifter](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/exodrifter/32/506103_2.png) [@exodrifter](https://meta.discourse.org/u/exodrifter)
#### Post date: [9월 14, 2026, 5:38오전 UTC](https://meta.discourse.org/t/backup-upload-failure-due-to-uninitialized-transfermanager/409303/4 "2026-09-14T05:38:55Z")

</div>

네, 공식 Discourse Docker 설치를 사용하고 있는 것 같습니다. 확실하게 확인할 수 있는 방법이 있을까요? 설치를 한 지 꽤 시간이 지났거든요.

업데이트를 위해 `./launcher rebuild app` 명령을 실행했습니다. 이 명령은 컨테이너가 완전히 다시 빌드되었음을 의미한다고 생각하지만, 제가 잘못 알고 있는 건 아닌지 궁금합니다.

관련이 있을 수 있는 몇 가지 추가 정보:

- Ubuntu 24.04.4 LTS를 사용 중입니다.
- `app.yml`에서 `after_code` 훅을 통해 공식 `docker_manager` 및 `discourse-doc-categories` 플러그인을 설치합니다. `app.yml`에는 다른 플러그인이 정의되어 있지 않습니다.
- 백업 파일을 Backblaze에서 제공하는 S3 호환 스토리지에 저장하려고 하고 있으며, 이전에는 정상적으로 작동했습니다.

---

<div class="post-metadata">

### Author: ![Ethsim2](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/ethsim2/32/522255_2.png) [@Ethsim2](https://meta.discourse.org/u/Ethsim2)
#### Post date: [9월 14, 2026, 7:35오전 UTC](https://meta.discourse.org/t/backup-upload-failure-due-to-uninitialized-transfermanager/409303/5 "2026-09-14T07:35:09Z")

</div>

이 문제를 좁혀 보는 데 도움이 될 수 있는 한 가지 방법은 실행 중인 컨테이너 내에서 실제로 로드되고 있는 `aws-sdk-s3` 게임을 확인하는 것입니다.

`Aws::S3::TransferManager`를 도입한 Discourse의 변경 사항은 `aws-sdk-s3` 버전을 1.182.0에서 1.227.0으로 올렸습니다:

> <https://github.com/discourse/discourse/commit/7518750a5d4749eb30c58c36f1642b521dcd56b0>
>
> Previously, S3 backups and uploads larger than the multipart threshold
> crashed w…ith \`undefined method 'downcase' for nil\` whenever
> \`AWS\_REQUEST\_CHECKSUM\_CALCULATION\` was set to \`when\_required\` (a common
> setup for S3-compatible providers such as Cloudflare R2, Backblaze B2,
> and MinIO), because of a bug in \`aws-sdk-s3\` 1.182.0's multipart
> uploader.
> 
> This change bumps \`aws-sdk-s3\` to 1.227.0 — which respects
> \`when\_required\` in multipart uploads — and adapts to its API changes:
> moving off the newly-deprecated
> \`Aws::S3::Object#upload\_file\`/\`#download\_file\` onto
> \`Aws::S3::TransferManager\`, and reading the ETag back from the
> destination now that multipart copies no longer return a response.

링크하신 Discourse 리비전에서는 `Gemfile.lock`이 여전히 `aws-sdk-s3` 1.227.0을 사용해야 하며, 이 버전은 `Aws::S3::TransferManager`를 제공합니다.

컨테이너에 진입해 보실 수 있을까요:

```bash
cd /var/discourse

```

```bash
./launcher enter app

```

그리고 컨테이너 내에서 다음을 실행해 주세요:

```bash
cd /var/www/discourse

```

```bash
bundle info aws-sdk-s3

```

```bash
bundle exec ruby -e '
require "aws-sdk-s3"
puts "gem: #{Gem.loaded_specs["aws-sdk-s3"]&.full_name}"
puts "path: #{Gem.loaded_specs["aws-sdk-s3"]&.full_gem_path}"
p Aws::S3.autoload?(:TransferManager)
p Aws::S3::TransferManager
'

```

Rails 환경에서 애플리케이션 자체를 확인하는 것도 유용할 수 있습니다:

```bash
RAILS_ENV=production bundle exec rails runner '
puts "aws-sdk-s3: #{Gem.loaded_specs["aws-sdk-s3"]&.version}"
p Aws::S3.autoload?(:TransferManager)
p Aws::S3::TransferManager
'

```

그리고 다음 명령어로 컨테이너를 종료하세요:

```bash
logout

```

만약 여기서 더 오래된 `aws-sdk-s3` 버전이 보고되거나 `TransferManager`가 없다면, 이는 백업 예외를 설명해 줄 것이며 컨테이너에 설치된 게임들이 현재 Discourse `Gemfile.lock`과 일치하지 않는다는 것을 시사합니다.

1.227.0이 보고되고 `Aws::S3::TransferManager`가 성공적으로 해결된다면, 문제는 더 드문 경우에 해당하며 Sidekiq 백업 프로세스와 해당 인터랙티브 환경 사이의 차이점을 살펴봐야 한다는 것을 알 수 있습니다.

`./launcher rebuild app`를 사용 중이시므로, 이는 표준 [`discourse_docker`](https://github.com/discourse/discourse_docker) 워크플로우처럼 보입니다. 위의 명령어들은 재빌드된 컨테이너에 실제로 무엇이 들어갔는지를 더 정확하게 알려줄 것입니다.

---

<div class="post-metadata">

### Author: ![exodrifter](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/exodrifter/32/506103_2.png) [@exodrifter](https://meta.discourse.org/u/exodrifter)
#### Post date: [9월 14, 2026, 5:19오후 UTC](https://meta.discourse.org/t/backup-upload-failure-due-to-uninitialized-transfermanager/409303/6 "2026-09-14T17:19:02Z")

</div>

aws-sdk-s3의 오래된 버전을 사용하고 있는 것 같습니다.

```plaintext
$ bundle info aws-sdk-s3
  * aws-sdk-s3 (1.177.0)
	Summary: AWS SDK for Ruby - Amazon S3
	Homepage: https://github.com/aws/aws-sdk-ruby
	Source Code: https://github.com/aws/aws-sdk-ruby/tree/version-3/gems/aws-sdk-s3
	Changelog: https://github.com/aws/aws-sdk-ruby/tree/version-3/gems/aws-sdk-s3/CHANGELOG.md
	Path: /var/www/discourse/vendor/bundle/ruby/3.4.0/gems/aws-sdk-s3-1.177.0

```

이 문제를 조사하면서, AWS SDK가 Backblaze와 함께 작동하지 않는 문제를 해결하기 위해 [이 임시 해결책](https://meta.discourse.org/t/cant-rebuild-due-to-aws-sdk-gem-bump-and-new-aws-data-integrity-protections/354217/49?u=exodrifter)을 사용했음을 기억해냈습니다. 해당 주제를 다시 살펴보니, [Backblaze가 API를 업데이트](https://meta.discourse.org/t/cant-rebuild-due-to-aws-sdk-gem-bump-and-new-aws-data-integrity-protections/354217/53?u=exodrifter)하여 임시 해결책이 더 이상 필요 없게 되었습니다.

임시 해결책을 제거한 후 백업이 성공적으로 완료되었습니다! 도움 주셔서 감사합니다. ❤

---

<div class="post-metadata">

### Author: ![Ethsim2](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/ethsim2/32/522255_2.png) [@Ethsim2](https://meta.discourse.org/u/Ethsim2)
#### Post date: [9월 14, 2026, 5:32오후 UTC](https://meta.discourse.org/t/backup-upload-failure-due-to-uninitialized-transfermanager/409303/7 "2026-09-14T17:32:41Z")

</div>

이 글에서 한 가지 생각해보는 점은, 이러한 임시 호환성 템플릿은 무기한으로 Discourse의 종속성을 덮어쓰는 것보다, 자체 만료/가드 조건이 있는 것이 더 안전할 수 있다는 것입니다.

예를 들어, 임시 소스 백포트를 위해 프로덕션에서 훅을 사용할 계획인데, 먼저 업스트림 수정 사항이 이미 존재하는지 확인하고, 여전히 필요한 경우에만 패치를 적용할 예정입니다.

이 경우, 다음과 같은 방식이 Discourse 자체가 더 새로운 SDK 기능을 의존하기 시작했을 때 오래된 `aws-sdk-s3 1.177.0` 고정(pin)이 계속 유지되는 것을 방지할 수 있었을 것입니다:

```yaml
hooks:
  after_bundle_exec:
    - exec:
        cd: $home
        cmd:
          - |
            if grep -q "Aws::S3::TransferManager" lib/s3_helper.rb; then
              echo "Discourse now requires Aws::S3::TransferManager; skipping obsolete Backblaze aws-sdk-s3 downgrade"
            else
              echo "Applying temporary Backblaze aws-sdk-s3 compatibility pin"
              bundle config set frozen false
              sed -i 's/gem "aws-sdk-s3", require: false/gem "aws-sdk-s3", "1.177.0", require: false/' Gemfile
              bundle update aws-sdk-s3
              bundle add aws-sdk-core --version 3.215
            fi

```

해당 체크는 단순히 예시를 위한 것입니다. 더 일반적인 버전 체크나, Discourse가 예상 SDK 버전을 넘어갈 때 명시적으로 실패하도록 하는 것이 더 나은 방법이 될 것입니다.

Discourse가 기대하는 버전과 더 이상 일치하지 않는 gems를 가진 컨테이너를 조용히 생성하는 것보다, 크게 실패(fail loudly)하는 것이 훨씬 나을 것입니다.

---

<div class="post-metadata">

### Author: ![exodrifter](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/exodrifter/32/506103_2.png) [@exodrifter](https://meta.discourse.org/u/exodrifter)
#### Post date: [9월 14, 2026, 5:52오후 UTC](https://meta.discourse.org/t/backup-upload-failure-due-to-uninitialized-transfermanager/409303/8 "2026-09-14T17:52:42Z")

</div>

소음이 크고 명확하게 실패하는 것이 나았을 것이라는 데에는 동의하지만, 이전부터 Discourse가 기대하는 버전과 일치하지 않는 게름을 _원했기_ 때문이었습니다. 새로운 `aws-sdk-s3` 버전은 Backblaze가 지원하지 않는 헤더를 전송했고, 저는 백업이 작동하기를 원했기 때문입니다.

우회책이 더 이상 필요 없어졌을 때를 알릴 수 있도록 사전에 설정할 수 있는 체크가 있었는지 모르겠습니다. 저는 2025년 4월, 수정이 가능해지기 전에 1년 반 전에 이 우회책을 구현했습니다.

제가 할 수 있는 최선은 만료일을 추가하여 우회책이 여전히 필요한지 확인하도록 강제하는 것이었을 것입니다. 이러한 기능은 좋을 수 있습니다. 아니면, 우회책이 여전히 필요한지 확인하도록 리마인더를 설정하는 등 더 능동적으로 행동할 책임은 저에게 있을 수도 있습니다. 그 점에서 [몇 가지 메모](https://www.exodrifter.space/notes/discourse-s3-unsupported-header-amz-checksum-crc32)가 여기에서 도움이 되었습니다.

---

<div class="post-metadata">

### Author: ![Ethsim2](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/ethsim2/32/522255_2.png) [@Ethsim2](https://meta.discourse.org/u/Ethsim2)
#### Post date: [9월 23, 2026, 8:13오전 UTC](https://meta.discourse.org/t/backup-upload-failure-due-to-uninitialized-transfermanager/409303/9 "2026-09-23T08:13:24Z")

</div>

오늘 제가 매우 유사한 상황에 직면한 후, 몇 가지 추가 의견을 드립니다.

저는 병합되지 않은 Discourse PR에 대해 `app.yml`에 임시 소스 백포트를 적용하고 있었습니다. 해당 훅은 다음과 같이 사용되었습니다:

```bash
git apply --check /tmp/patch &&
  git apply /tmp/patch

```

그 후 업스트림에서 해당 영역 중 하나가 리팩토링되어, 기존 패치가 더 이상 깨끗하게 적용되지 않았습니다. `git apply --check`는 제가 원했던 대로 정확히 작동했습니다. 패치가 부분적으로 적용되지 않았고, 재구축이 조용하게 불일치한 체크아웃을 생성하는 대신 명확하게 실패했습니다.

그러나 중요한 단점이 있었습니다. 이 문제가 `./launcher rebuild app` 실행 중에 발생했기 때문에, 재구축 실패로 인해 구식 훅을 제거하고 다시 재구축할 때까지 `app` 컨테이너가 사용 불가능한 상태가 되었습니다.

따라서 저는 이전 제안을 약간 수정할 것 같습니다. 임시 프로덕션 우회책/백포트의 경우, 가장 안전한 접근 방식은 다음과 같은 것들의 조합인 것 같습니다:

- 제안하신 대로 명시적인 검토/만료 날짜;
- 신뢰할 수 있는 경우를 위해 세맨틱/버전 가드;
- 실용적인 범위 내에서 프로덕션 재구축을 시작하기 **이전** 에 사전 적용 가능성 확인;
- 그리고 최종 안전망으로 `git apply` 직전에 여전히 `git apply --check`를 사용하는 것.

제 경우라면 만료/리마인더가 우회책을 재검토하도록 알려주었을 것이고, 적용 가능성 확인은 오래된 패치가 더 새로운 Discourse 체크아웃을 조용히 수정하는 것을 방지했을 것입니다.

따라서 만료 날짜에 대한 당신의 주장은 이제 저에게 더 합리적으로 느껴집니다. 특히 원래 우회책이 의도적으로 설치를 업스트림과 다르게 만드는 경우, "이 우회책이 여전히 필요한가?"에 대한 완벽한 자동 테스트가 항상 존재하지는 않기 때문입니다.
