최근 업데이트가 많았습니다. 그중 하나가 제목(subject line)을 망가뜨렸고(더 이상 카테고리가 포함되지 않음), 지금은 메일이 아예 발송되지 않습니다. 사용자들은 매우 불만입니다. 이 문제를 디버깅하는 방법을 모르겠습니다. 에러 로그는 어디서 볼 수 있을까요? 사이드키(Sidekiq) 큐에 대한 페이지가 있는 것 같은데, 찾을 수가 없습니다. 도움을 주시면 감사하겠습니다.
네, 어제 업데이트 이후로 이메일 알림이 트리거되지 않는 것 같다는 걸 나도 알아차렸어요. 다만 다이제스트/요약은 여전히 작동하고 있긴 하죠. 우리만 이렇게 겪고 있는 건가요?
이 원인은 sidekiq가 예약된 작업을 처리해야 할 때 실패할 수 있습니다.
오늘早些 우리 CD 사이트에서 동일한 문제를 확인했습니다. 다음 커밋 이상으로 업데이트되어 있는지 확인하세요:
(이 커밋이라고 생각하지만 100% 확신은 없습니다)
문제가 동일한지 확인하려면 /sidekiq에서 예약된 작업을 확인하고 과거 날짜의 작업이 있는지 살펴보세요.
네, 그 영향으로 저희도 피해를 봤습니다. 업데이트로 해결되었습니다.
latest-release +103에서 수백 건의 실패한 Sidekiq 작업을 확인했습니다
latest-release +153에서 수정되었습니다
최신 버전으로 업데이트했지만 내 사이트 중 하나에서 여전히 이메일 전송 문제가 발생합니다. 테스트 이메일을 보내면 오류 메시지만 표시됩니다.
오류 - end of file reached
지금은 모바일에서 확인 중이며, 컴퓨터 앞에 앉으면 sidekiq와 로그를 확인하겠습니다. 다른 곳에서 살펴볼 수 있는 제안이 있을까요?
Backtrace
Message (5 copies reported)
Job exception: end of file reached
Backtrace
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/net-protocol-0.2.2/lib/net/protocol.rb:237:in `rbuf_fill'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/net-protocol-0.2.2/lib/net/protocol.rb:199:in `readuntil'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/net-protocol-0.2.2/lib/net/protocol.rb:209:in `readline'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/net-smtp-0.5.1/lib/net/smtp.rb:1017:in `recv_response'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/net-smtp-0.5.1/lib/net/smtp.rb:676:in `block in do_start'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/net-smtp-0.5.1/lib/net/smtp.rb:1027:in `critical'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/net-smtp-0.5.1/lib/net/smtp.rb:676:in `do_start'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/net-smtp-0.5.1/lib/net/smtp.rb:642:in `start'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/mail-2.9.0/lib/mail/network/delivery_methods/smtp.rb:154:in `start_smtp_session'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/mail-2.9.0/lib/mail/network/delivery_methods/smtp.rb:108:in `deliver!'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/mail-2.9.0/lib/mail/message.rb:269:in `deliver!'
/usr/local/lib/ruby/3.3.0/delegate.rb:87:in `method_missing'
/var/www/discourse/lib/email/sender.rb:296:in `send'
/var/www/discourse/app/jobs/regular/download_backup_email.rb:19:in `execute'
/var/www/discourse/app/jobs/base.rb:318:in `block (2 levels) in perform'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rails_multisite-7.0.0/lib/rails_multisite/connection_management/null_instance.rb:49:in `with_connection'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rails_multisite-7.0.0/lib/rails_multisite/connection_management.rb:17:in `with_connection'
/var/www/discourse/app/jobs/base.rb:305:in `block in perform'
/var/www/discourse/app/jobs/base.rb:301:in `each'
/var/www/discourse/app/jobs/base.rb:301:in `perform'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:220:in `execute_job'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:185:in `block (4 levels) in process'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:180:in `traverse'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in `block in traverse'
/var/www/discourse/lib/sidekiq/suppress_user_email_errors.rb:6:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in `traverse'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in `block in traverse'
/var/www/discourse/lib/sidekiq/discourse_event.rb:6:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in `traverse'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in `block in traverse'
/var/www/discourse/lib/sidekiq/pausable.rb:131:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in `traverse'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in `block in traverse'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/job/interrupt_handler.rb:9:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in `traverse'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:183:in `block in traverse'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/metrics/tracking.rb:26:in `track'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/metrics/tracking.rb:134:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:182:in `traverse'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/middleware/chain.rb:173:in `invoke'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:184:in `block (3 levels) in process'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:145:in `block (6 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/job_retry.rb:118:in `local'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:144:in `block (5 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/config.rb:39:in `block in <class:Config>'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:139:in `block (4 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:281:in `stats'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:134:in `block (3 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/job_logger.rb:15:in `call'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:133:in `block (2 levels) in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/job_retry.rb:85:in `global'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:132:in `block in dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/job_logger.rb:40:in `prepare'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:131:in `dispatch'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:183:in `block (2 levels) in process'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:182:in `handle_interrupt'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:182:in `block in process'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:181:in `handle_interrupt'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:181:in `process'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:86:in `process_one'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/processor.rb:76:in `run'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/component.rb:10:in `watchdog'
/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/sidekiq-7.3.9/lib/sidekiq/component.rb:19:in `block in safe_thread'
방금 노트북에서 이메일 전송 테스트를 다시 해보니 다음과 같은 메시지가 나타납니다:
테스트 이메일을 보내는 중 문제가 발생했습니다. 메일 설정을 다시 확인하고, 호스트가 메일 연결을 차단하지 않는지 확인한 후 다시 시도해 주세요.
그리고 자바스크립트 콘솔에는 다음과 같은 내용이 표시됩니다:
제 문제는 다른 것일 수도 있습니다 - mailgun 쪽으로 확인해 보겠습니다.
수정: 재시도(retries)에서 두 개의 오류를 발견하여 삭제했습니다. 하지만 불행히도 테스트 시 여전히 같은 오류가 발생합니다. 또한 SMTP 서버도 확인했는데 정상 작동하는 것으로 보입니다.
Tobias님, 안녕하세요!
사용자님의 문제는 다르며, 초기 연결이 성공한 직후 응답을 기다리다가 연결이 끊어지는 현상이 발생하고 있습니다.
잘못된 포트에 잘못된 프로토콜로 통신을 시도하고 있는 것은 아닐까요… 현재 어떤 설정을 사용하고 계신가요?
최근 로직과 오류 메시지가 업데이트된 rake emails:test 태스크를 실행하면 다른 오류가 표시됩니까?
마이클, 안녕하세요! 답변해 주셔서 감사합니다. 여러분이 너무 보고 싶어요! ![]()
음.. 제가 제 사이트를 DO에서 Hetzner로 이전했는데, 몇 주간은 잘 작동했어요. 제 다른 사이트도 잘 작동하고 있구요. 정말 수수께끼 같은 상황이네요. 약 일주일 전쯤 갑자기 작동을 멈췄고, 확인해 보니 오류가 나고 있었습니다. Hetzner(도움을 거부함)와 Mailgun에 도움을 요청했습니다. Mailgun의 답변은 다음과 같습니다:
답변 주셔서 감사합니다. 저희가 확인한 마지막 인증된 수신 이벤트는 1월 11일에 SMTP로 전송된 것이었습니다.
어떤 변경 사항이 있었는지 확인해 주시겠어요? 검토를 위해 전송 애플리케이션 설정의 스크린샷과 전송 애플리케이션/SMTP 전송 로그의 관련 오류를 제공해 주십시오.
혹시 비밀번호 문제인 것 같아서 Mailgun 비밀번호를 변경하고 다시 시도해 보았지만, 여전히 실패했습니다.
rake emails:test 출력 내용:
root@ubuntu-4gb-nbg1-1-app:/var/www/discourse# rake emails:test
Testing sending to using smtp.mailgun.org:587, username:postmaster@domain with plain auth.
====================================================================================== ERROR =======================================================================================
UNKNOWN ERROR!
EOFError: end of file reached
===================================================================================== SOLUTION =====================================================================================
This is not a common error. No recommended solution exists!
Please report the exact error message above to https://meta.discourse.org/
(And a solution, if you find one!)
====================================================================================================================================================================================
로그인을 시도하기 전에 이미 실패하는 것 같습니다.
Discourse를 변수에서 제외하기 위해 호스트에서 그리고 컨테이너 내부에서 모두 시도해 보세요:
$ openssl s_client -connect smtp.mailgun.org:587 -starttls smtp
다양한 출력이 표시된 후 인증을 시도할 수 있어야 합니다:
○ → openssl s_client -connect smtp.mailgun.org:587 -starttls smtp
Connecting to 34.160.63.108
CONNECTED(00000003)
…
SSL-Session:
…
---
read R BLOCK
EHLO localhost
250-2ed1d46f4d7dec773e2a97b59f3a3bf8a2d6db54f94eead5dcf49e3ea1caac18
250-AUTH PLAIN LOGIN
250-SIZE 52428800
250-8BITMIME
250-SMTPUTF8
250 PIPELINING
AUTH PLAIN bWljaGFlbABtaWNoYWVsAHBhc3N3b3Jk
501 Username used for auth is not valid email address
535 Authentication failed
closed
입력해야 하는 문자열은 다음과 같습니다:
EHLO localhost
AUTH PLAIN bWljaGFlbABtaWNoYWVsAHBhc3N3b3Jk
(해당 문자열은 michael/password 자격 증명이므로 당연히 작동하지 않지만, 수동으로 시도해 보고 싶다면 실제 자격 증명을 위한 문자열을 구성하는 방법을 이 게시물에서 배울 수 있습니다)
직접적으로 무엇이 작동하고 무엇이 실패하는지 확인하는 것이 도움이 될 것입니다.
사용 가능한 경우 swaks를 사용해보는 것도 좋습니다 - 설치할 수 있는 OS 패키지일 가능성이 높습니다.
조금 더 쉽습니다. 예를 들어 다음과 같이 사용할 수 있습니다:
swaks --to frodo@shire.net --from bilbo@shire.net --auth PLAIN --auth-user bilbo --auth-password ring --server smtp.mailgun.org:587 --tls
다만 실제 자격 증명을 사용하면 됩니다.
해당 명령의 출력도 문제를 파악하는 데 도움이 될 수 있습니다.
swaks를 시도해 보았는데 다음과 같은 결과가 나왔습니다:
=== Trying smtp.mailgun.org:587...
=== Connected to smtp.mailgun.org.
*** Remote host closed connection unexpectedly.
이로 인해 다른 서버에서 swaks를 실행해 보게 되었고, 거기서는 "Great success"라는 메시지가 표시되었습니다. 꽤 귀여운 메시지네요!
<~ 250 Great success
~> QUIT
<~ 221 See you later. Yours truly, Mailgun
=== Connection closed with remote host.
따라서 문제는 Mailgun이 제 서버를 차단하고 있거나, 제 서버 설정에 문제가 있는 것 중 하나일 것입니다. Mailgun에 문의해 보고, 그래도 해결되지 않으면 서버를 삭제한 후 다시 구축할 예정입니다.
당연한 말씀입니다. 이는 기본적으로 동일한 오류입니다.
의심하신 대로, 가장 가능성 있는 원인은 외부 요인이 연결을 방해하고 있기 때문입니다.
포트 587 대신 2525를 사용해야 한다는 의심이 드네요
Hetzner는 포트 587을 차단하지 않는다고 명시적으로 밝히고 있습니다.
또한, 실제로 차단하고 있다면 연결을 확립하지 못했다는 오류로 나타날 가능성이 높습니다.
이로 인해 Discourse와 Mailgun 설정 문제는 거의 배제되었습니다.
이 시점에서 가장 유용한 진단 방법은 영향받는 서버에서 대체 Mailgun 제출 포트(2525)를 시도하는 것입니다:
openssl s_client -connect smtp.mailgun.org:2525 -starttls smtp
(또는 swaks를 사용하여 동일한 테스트를 수행할 수 있습니다.)
Mailgun은 방화벽, 출구 필터링, 또는 제공업체 수준의 네트워크 규칙에 의해 587 포트가 방해받는 환경을 위해 특별히 2525 포트를 지원합니다.
만약:
- 2525는 작동하지만 587은 작동하지 않음 → 네트워크 / IP / 라우팅 간섭일 가능성이 매우 높음
- 둘 다 실패 → 외부 요인이 연결을 차단하거나 종료하고 있다는 더 강력한 증거
어떤 경우든, 이 동작은 Discourse나 Sidekiq의 회귀(regression)보다는 "외부 연결 간섭"에 훨씬 더 부합합니다.
아직 mailgun에서 답변을 받지 못했습니다. 그들이 도움을 줄 수 없다면 Hetzner의 새 서버로 처음부터 다시 시작할 계획입니다.
swaks로 다른 포트도 시도해 보았는데, 흥미롭게도 2525 포트에서도 동일한 오류가 발생했고, 지연 없이 즉시 나타났습니다.
=== Trying smtp.mailgun.org:2525...
=== Connected to smtp.mailgun.org.
*** Remote host closed connection unexpectedly.
하지만 25와 465 포트에서는 다른 오류가 발생했고, 응답이 오는 데 몇 초가 걸렸습니다.
=== Trying smtp.mailgun.org:25...
*** Error connecting to smtp.mailgun.org:25:
*** Connection timed out
=== Trying smtp.mailgun.org:465...
*** Error connecting to smtp.mailgun.org:465:
*** Connection timed out
이것이 무슨 의미인지 잘 모르겠습니다. 아마도 서버의 방화벽 설정이 잘못되어 일부 포트가 차단되고 있는 것 같습니다.
그것은 의도적이고 예상되는 것입니다.
Hetzner는 기본적으로 해당 포트들을 차단합니다.
말이 되네요. 그런데 25번과 465번 포트가 다른 포트들보다 실패하는 데 더 걸렸다는 점이 흥미롭네요. 어쨌든 급한 일은 아니니 Mailgun 쪽에서 답변을 기다려 보겠습니다. 이건 제 가족 사이트를 위한 것이니, 이메일을 기다리기만 하지 말고 로그인해서 알림에 변경 사항이 있는지 직접 확인해 주시길 권합니다.
내일 가족을 만나러 그리고 장례식에 참석하기 위해 독일로 갑니다. 다음 주에 이 문제를 다시 살펴보고, 아마도 새 서버를 설정해서 처음부터 다시 시작할 것 같습니다.
모든 조언에 감사드립니다! 이 과정을 통해 정말 많은 것을 배웠습니다. swaks 도구도 정말 마음에 듭니다.
타이밍은 실제로 유용한 정보일 수 있습니다.
포트(또는 더 일반적으로 트래픽)가 차단될 때, 이는 드롭(침묵 거부) 또는 리젝트(발신元に “unreachable” 메시지, 예: port unreachable가 반환됨)로 차단될 수 있습니다.
25/465 포트에서 관찰되는 침묵 드롭은 연결 시도가 이루어진 후 타임아웃이 도달할 때까지 아무 일도 일어나지 않는 상태를 유발합니다.
리젝트는 “Connection refused” 또는 "Port unreachable"와 같은 메시지를 유발합니다.
이는 의도된 동작을 나타내는 것입니다 - 연결이 이루어진 후 즉시 연결이 종료되고 있습니다.
소스(출처)를 변경했으므로, 다음으로 시도해 볼 수 있는 것은 대상(목적지)을 변경하는 것입니다. 예를 들어 smtp.gmail.com 또는 smtp.office365.com에 대해 동일한 명령을 실행해 보세요. 인증 실패가 발생해야 하며, 이는 Mailgun이 귀하를 특별히 거부하고 있음을 강력하게 시사합니다.
@supermathie의 설명은 정확합니다 ![]()
타이밍 차이는 실제로 노이즈가 아니라 유용한 신호입니다.
보시는 내용을 요약하면 다음과 같습니다:
- 25 / 465 타임아웃 → 조용한 드롭 (Hetzner 정책 수준의 차단, 예상되는 상황)
- 2525 연결 후 즉시 닫힘 → TCP 경로는 정상적이지만, 원격 측에서 세션을 종료하고 있음
마지막 항목이 핵심입니다.
그 이유는 다음과 같습니다:
- TCP 핸드셰이크가 성공합니다
- TLS 협상이 실제로 시작되지 않습니다
- 그리고 즉시 발생하기 때문입니다
…이는 Mailgun이 초기 단계에서 연결을 거부하고 있으며, Discourse, Sidekiq, 또는 Ruby의 문제가 아님을 강력히 시사합니다.
최근 우리가 목격한 몇 가지 상황과 일치합니다:
- IP 평판 / 지역 기반 필터링
- 아직 신뢰되지 않은 새로운 Hetzner IP 범위
- 또는 SMTP 배너 교환 전의 Mailgun 측 정책 검사
Discourse에서 이러한 즉각적인 원격 소켓 클로저를 일으킬 만한 것은 없습니다 - Sidekiq은 단순히 메시지를 Net::SMTP에 전달하고 기다릴 뿐입니다.
나중에(전혀 급하지 않으니) 한 가지 더 확실한 확인을 원하신다면:
openssl s_client -connect smtp.gmail.com:587 -starttls smtp
적절한 SMTP 배너를 받고 인증 실패가 발생해야 합니다 - 이는 기본적으로 아웃바운드 SMTP 자체는 정상이고, 다르게 행동하는 엔드포인트가 Mailgun뿐임을 증명할 것입니다.
이 상황을 잠시 중단하는 것도 완전히 이해합니다 - 특히 주어진 상황을 고려할 때요.
다른 모든 일 위에 이것까지 처리하셔야 해서 정말 죄송합니다 ![]()
Mailgun에서 유용한 답변이 오면 좋겠지만, 솔직히 새로 시작하거나 제공업체를 변경하는 것(Brevo, Postmark 등)이 SMTP 평판 문제를 기다리는 것보다 종종 더 빠릅니다.
이미 이 문제를 정확히 디버깅하셨습니다 - 여기서 언급된 것 중 어느 것도 당신이 무언가를 놓쳤거나 Discourse를 잘못 설정했다는 것을 시사하지 않습니다.
독일로의 여행에 안전을 기원하며, 잘 챙기시길 바랍니다.

