왜 이메일 반송률 8.3%가 하루 발송량을 절반으로 깎았나
이메일 반송은 받는 쪽 메일 서버가 '이 주소로는 배달할 수 없다'며 메일을 돌려보내는 일이다. 반송이 쌓이면 보내는 쪽의 발신 평판이 흔들린다. 우리 발송 스크립트가 메일 사이에 3초씩 간격을 두는 이유도 이 평판 때문이고, 코드 주석은 반송률 5%를 위험선으로 적어 두었다.
그래서 발송 스크립트에는 반송률이 높으면 하루 발송 상한을 절반으로 낮추는 규칙이 들어 있다. 2026년 8월 4일에 이 규칙이 작동하고 있었다. 반송률은 8.3%였고 하루 상한은 100통에서 50통으로 내려가 있었다. 하루 100곳에 영업 메일을 보내던 자동 발송이 50곳에서 멈추는 상태였다.

이런 일이 처음은 아니었다. 2026년 7월 20일에는 125통 중 9통이 반송돼 반송률이 7.2%였다. 그때 반송 주소를 들여다보니 대부분 폐업이나 도메인 만료로 도메인 자체가 사라진 주소였다. 그래서 발송 전에 DNS를 한 번 조회해, 메일을 받을 기록이 없는 도메인을 거르는 검사를 넣었다.
그 검사를 넣은 뒤인 8월 4일에도 반송률은 8.3%였다. 도메인이 살아 있는 주소에서 반송이 계속 나고 있었다. 두 시점의 발송 대상이 달라 두 숫자를 곧바로 비교할 수는 없다. 그래도 DNS 검사만으로 반송을 막지 못한다는 사실은 분명했다.
처음 잰 숫자 — 반송된 40건은 어떤 검사를 통과했나
당시 발송 전 게이트는 두 겹이었다.
- DNS 검사 — 주소의 도메인에 메일 수신 기록(MX, 없으면 A 기록)이 실제로 있는지 조회한다. 4초 안에 답이 없거나 DNS 장애로 판정할 수 없으면 통과시킨다. 일시 장애 때문에 멀쩡한 리드를 영구히 버리는 손해가 반송 한 건보다 크다고 봤기 때문이다
- 공식 주소 대조 — 그 주소가 회사 홈페이지에 공식 연락처로 적혀 있는지 대조한다. 판정은 검증 통과·판단불가·미등재 셋으로 나오고, 신뢰도(high 등)를 함께 남긴다. 내부 스크립트 이름을 따서 census라고 부른다
반송 목록은 Resend의 배달 상태를 주기적으로 조회해 쌓는다. 한 줄에 주소 하나씩 적힌 목록이고, 여기 오른 주소는 다시는 보내지 않는다. 이 목록의 반송 40건을 두 검사의 판정과 하나씩 맞춰 봤다.
결과는 한쪽으로 쏠려 있었다. 40건 중 32건이 공식 주소 대조에 등재돼 있었고, 신뢰도도 high였다. 도메인은 살아 있었고, 주소는 그 회사 홈페이지에 공식 연락처로 올라 있었다. 두 게이트를 모두 통과한 주소가 반송의 대부분을 차지했다.
다만 이 숫자만으로는 무엇을 고칠지 정할 수 없었다. 반송 주소 대부분이 검증 통과였다는 사실은, 애초에 우리가 보내는 주소 대부분이 검증 통과라서 생긴 결과일 수도 있다. 반송 건수가 아니라 판정별로 보낸 주소 가운데 몇 %가 반송됐는지를 따로 재야 했다.
세운 가설 — 공식 주소로 확인된 곳에만 보내면 반송이 준다
대책으로 먼저 나온 안은 공식 주소 대조를 발송 큐의 필수 조건, 곧 하드 게이트로 올리는 방법이었다. 검증 통과 판정을 받은 주소에만 보내고 나머지는 큐에서 빼자는 안이다.
논리는 직관적이었다. 홈페이지에 공식 연락처로 올린 주소라면 회사가 실제로 쓰는 주소일 테고, 어디서 모였는지 모르는 주소는 반송 위험이 클 테니, 공식 주소만 남기면 반송이 줄어든다는 추론이다. 반송 40건 중 32건이 검증 통과였다는 숫자와는 어긋나 보였지만, 앞에서 적은 대로 그 숫자는 모수 차이로도 설명할 수 있었다.
이 가설은 확인 방법이 분명했다. 가설이 맞다면 판정별 반송률은 검증 통과가 가장 낮고 미등재가 가장 높아야 한다. 이미 보낸 주소를 판정별로 나누고, 묶음마다 반송 비율을 세면 답이 나온다.
가설이 틀린 지점 — 검증 통과 주소가 2배 더 반송됐다
판정별로 나눠 센 결과는 예측과 정반대였다.

검증 통과 174건 중 9.8%, 판단불가 128건 중 11.7%, 미등재 162건 중 4.9%가 반송됐다. 공식 주소로 확인된 묶음이 확인되지 않은 묶음보다 2배 더 반송됐다. 가장 깨끗한 묶음은 오히려 미등재였다.
하드 게이트로 걸었을 때의 비용도 셌다. 검증 통과만 보내면 발송 큐가 1,876곳에서 980곳으로 48% 줄어든다. 큐가 반토막 나는데, 남는 묶음의 반송률은 9.8%로 걸러 낸 미등재 묶음의 4.9%보다 높다. 반송을 줄이려고 건 게이트가 반송률 낮은 주소를 골라 버리는 셈이었다.
공식 주소 대조는 커버리지도 좁았다. 판정을 낼 수 있는 범위가 46%였다. 절반이 넘는 주소는 애초에 검증 통과를 받을 기회가 없으니, 하드 게이트는 그만큼 큐를 더 깎는다.
단서도 달아 둔다. 이 비교는 관측 비교다. 주소를 무작위로 나눠 보낸 실험이 아니라 이미 보낸 주소를 사후에 판정별로 나눴으니, 묶음마다 업종이나 회사 규모가 달랐을 수 있다. 그래도 방향이 반대로 나온 이상 '검증 통과면 안전하다'는 근거는 서지 않는다. 하드 게이트 안은 여기서 기각했다.
진짜 원인은 무엇이었나 — 공식 주소인지와 메일함이 살아 있는지는 다른 질문
두 게이트가 각각 무엇을 묻는지 한 줄씩 적어 보면 빈자리가 보인다.
| 검사 | 묻는 질문 | 보지 못하는 것 |
|---|---|---|
| DNS 검사 | 이 도메인이 메일을 받을 수 있나 | 도메인 안의 개별 계정 |
| 공식 주소 대조 | 이 주소가 홈페이지에 적힌 공식 주소인가 | 그 계정이 지금도 있는지 |
| (비어 있던 자리) | 이 메일함이 지금 살아 있나 | — |
반송은 셋째 질문의 영역이다.
공식 주소 대조는 '이 주소가 공식인가'를 보는 도구지, '그 메일함이 살아 있나'를 보는 도구가 아니다. 홈페이지에 한 번 적힌 주소는 그 계정이 없어진 뒤에도 그대로 남는다. 도메인은 살아 있고 홈페이지에도 적혀 있으니 두 게이트를 다 통과하지만, 받는 서버에는 그 계정이 없어 메일이 돌아온다. 반송 40건 중 32건이 이 경우였다.
검증 통과 묶음의 반송률이 더 높은 이유까지는 이번에 확인하지 않았다. 홈페이지에 오래 걸려 있던 주소일수록 계정이 정리됐을 수 있다는 짐작은 가능하지만, 짐작일 뿐이어서 판정 근거로 쓰지 않았다. 확실한 사실은 하나다. 반송을 가르는 질문은 계정 단위였고, 우리 게이트는 그 질문을 하지 않고 있었다.
조치 — 발송 직전에 SMTP RCPT로 계정이 있는지 묻는다
계정이 있는지 알려 줄 수 있는 곳은 받는 쪽 메일 서버뿐이다. 메일 서버끼리는 SMTP라는 정해진 대화 순서로 메일을 주고받는다. 보내는 쪽이 인사(EHLO)를 하고, 보내는 사람(MAIL FROM)과 받는 사람(RCPT TO)을 차례로 알린 뒤 본문(DATA)을 넘긴다. 받는 서버는 RCPT TO 단계에서 받는 사람 주소를 받을지 말지 답한다.
새 검사는 이 대화를 RCPT TO까지만 하고 끊는다. DATA를 보내지 않으니 메일은 한 통도 나가지 않는다. 받는 서버가 RCPT TO에 뭐라고 답하는지만 듣고 판정한다. 이 검사를 DNS 검사 바로 뒤, 발송 직전의 세 번째 층으로 넣었다.

구현에서 정한 값은 다음과 같다.
- 판정은 셋이다. reject(계정이 없다고 확정), ok(수락), unknown(판정 불가). 발송에서 빼는 판정은 reject 하나뿐이다
- 받는 서버의 응답은 15초까지 기다린다. 넘으면 판정 불가로 보고 통과시킨다. MX 기록 조회는 DNS 검사처럼 4초에서 끊는다
- 한 번에 6곳씩 동시에 확인한다. 하루 상한이 100통 이하라서 이 정도면 1분 안에 끝난다
- 25번 포트가 막힌 환경(일부 클라우드나 통신사 회선)에서는 모든 판정이 unknown이 되어 시간만 쓴다. 그래서 환경변수 하나로 이 검사를 통째로 건너뛸 수 있게 했다
판정할 수 없는 주소를 통과시키는 원칙은 DNS 검사에서 그대로 가져왔다. 확인이 안 된다는 이유로 주소를 버리면, 받는 서버의 일시 장애 한 번에 살아 있는 리드를 영구히 잃는다. 반송 한 건을 더 내는 편이 그보다 싸다고 판단했다.
다른 대책 두 가지는 왜 버렸나
SMTP RCPT 확인을 고르기 전에 대안 둘을 더 검토했다. 앞에서 기각한 하드 게이트까지 합쳐 셋을 한 표에 적는다.
| 대안 | 판정 | 사유 |
|---|---|---|
| 메일 제목의 광고 표기를 바꿔 스팸 필터 회피 | 기각 | 제목 맨 앞의 '(광고)'는 정보통신망법 제50조 제4항이 정한 법정 표기라 임의로 바꿀 수 없다 |
| 상용 이메일 검증 API | 기각 | 매달 고정비가 새로 생긴다. 발송 직전 RCPT 확인을 직접 하면 같은 신호를 얻을 수 있다고 봤다 |
| 공식 주소 대조를 하드 게이트로 | 기각 | 검증 통과 묶음의 반송률이 9.8%로 미등재 4.9%보다 높고, 큐만 1,876곳에서 980곳으로 줄인다 |
채택안은 받는 서버에 직접 묻는 SMTP RCPT 확인이다.
광고 표기는 바로 전 주에 이미 한 번 손본 자리였다. 2026년 7월 28일, 법령을 확인하다가 제목 템플릿 4개가 전부 대괄호 '[광고]'를 쓰고 있다는 사실을 찾았다. 법정 형식은 괄호 '(광고)'를 제목 맨 앞에 두는 방식이고, '광 고'처럼 띄워 쓴 변형은 명시적으로 금지된다. 그때까지 대괄호 형식으로 206건이 나가 있었고, 이후 발송분부터 괄호로 바꿨다. 법으로 정한 표기를 반송 대책 때문에 다시 흔들 수는 없었다.
조치에서 한 번 더 틀린 지점 — 5xx 거절은 모두 계정 없음인가
SMTP 응답은 세 자리 코드와 문구로 온다. 일반 규칙상 2로 시작하면 수락, 4로 시작하면 일시 거절, 5로 시작하면 영구 거절이다. 초판 분류기는 이 규칙에 기대 단순하게 판정했다. 5로 시작하는 거절이면 계정이 없다고 보고 발송에서 뺐다.
실측에서 이 규칙이 깨졌다. bd.com 도메인의 한 주소가 '550 5.7.1 … blocked using Spamhaus'라는 응답으로 거절됐다. 이 주소는 우리 메일에 실제로 회신한 적이 있는, 살아 있는 리드였다.
이 550은 계정이 없다는 뜻이 아니었다. 확인하러 간 우리 쪽 IP가 스팸 차단 목록인 Spamhaus에 올라 있어서 받는 서버가 요청을 거절했다. 이 검사는 가정용 회선을 쓰는 PC에서 돌고, 그 회선 IP가 Spamhaus에 등재돼 있었다. 실제 메일은 Resend의 IP로 나가니 발송 자체와는 상관이 없지만, RCPT 확인 요청은 이 PC에서 나간다. 초판대로라면 회신까지 한 리드를 계정 없음으로 판정해 영구히 버릴 뻔했다.
이 오판은 판별력 숫자를 양쪽으로 부풀렸다. 이미 반송된 주소 묶음(반송군)과 정상적으로 받은 주소 묶음(대조군)에 초판 분류기를 소급해 돌리자, 반송군의 57%를 걸러 내면서 대조군도 10%를 막았다. 57%라는 차단율에는 IP 차단 응답까지 계정 없음으로 센 몫이 섞여 있었다.
그래서 응답 코드 대신 응답 문구로 갈랐다. 계정이 없다고 밝힌 문구가 있고, 정책 차단 문구가 없을 때만 reject다. 두 문구가 함께 나오면 계정이 있는지 알 수 없으니 unknown으로 통과시킨다.

문구 목록은 실제로 받은 응답에서 출발했다. 국내 메일 호스팅인 하이웍스는 계정이 없으면 '505 this account is unknown user (#5.5.1)'로, 일반 메일 서버는 '550 5.1.1 User unknown'으로 답한다. 정책 차단 쪽은 spamhaus·blocked·denied·policy·reputation 같은 단어와 5.7로 시작하는 확장 코드를 잡는다.
ok도 그대로 믿지 않는다. 없는 주소에도 250을 돌려주는 catch-all 서버가 있어서 ok는 계정이 있다는 증명이 아니다. 4xx 그레이리스팅(처음 보는 발신자를 일단 미뤄 두는 방식)과 접속 실패도 모두 unknown으로 둔다.
이 판정 규칙이 다시 흔들리지 않도록 회귀 테스트 9개를 함께 넣었다. 하이웍스 계정 부재 2건, Spamhaus 정책 차단, 정상 수락은 8월 4일에 받은 실측 응답 문구를 그대로 쓴다. 나머지는 일반 메일 서버와 qmail의 계정 부재, 계정 문구와 정책 문구가 섞인 응답, 그레이리스팅, 일시 오류를 덮는다. 네트워크 없이 도는 순수 함수만 시험하므로 몇 초 안에 끝나고, 테스트가 깨지면 실제 발송에서 오차단이나 미차단이 난다는 신호로 읽는다.
재측정 결과 — 반송군 48% 차단, 정상 주소 오차단 0%
문구로 가른 분류기로 같은 두 묶음을 다시 쟀다. 반송군 차단율은 48%, 대조군 오차단율은 2%였다. 대조군을 수신거부 주소를 뺀 60건으로 다시 구성해 재자 오차단은 0%가 나왔다.

차단율만 보면 57%에서 48%로 떨어졌으니 나빠진 듯 보인다. 실제로는 IP 차단을 계정 없음으로 센 몫을 걷어 낸 값이다. 더 중요한 변화는 오차단이 10%에서 0%로 내려간 쪽이었다. 대조군에서 10%를 막는 게이트는 보내야 할 주소 열 곳 중 한 곳을 버린다.
이 판별력을 발송에 대입해 기대치를 계산했다. 반송될 주소의 절반 가까이를 발송 전에 걸러 내면 반송률 8.3%는 4%대로 내려가고, 반송률 규칙이 깎아 둔 하루 상한도 50통에서 100통으로 돌아온다. 새 검사는 받는 서버에 직접 묻기 때문에 공식 주소 대조처럼 커버리지 46%에 묶이지 않고, 큐 규모도 깎지 않는다.
변경은 8월 4일에 하나의 PR로 합쳤고, 다음 날 오전 9시 10분 크론부터 적용했다. 다만 여기 적은 판별력은 이미 반송된 주소에 소급해 잰 값이다. 4%대는 예상치이고, 배포 뒤 실제 반송률이 그만큼 내려왔는지는 이 기록에 없다. 그 확인은 다음 측정의 몫으로 남겼다.
남는 한계 — 이 검사가 볼 수 없는 주소들
새 검사에는 구조적으로 못 보는 자리가 있다.
- Outlook·Proofpoint 계열 — 확인 요청을 보내는 IP가 Spamhaus에 올라 있어서 이 계열 서버는 5.7.1 정책 거절을 돌려준다. 규칙상 이런 응답은 언제나 unknown이라 게이트가 걸리지 않는다. 확인 요청이 나가는 IP를 바꾸지 않는 한 이 커버리지 제한은 그대로다
- catch-all 서버 — 없는 주소에도 250을 준다. 이런 서버 뒤의 폐기 계정은 실제로 보내 봐야 드러난다
- 그레이리스팅과 접속 실패 — 판정 불가로 통과시키므로 이 경로로 새는 반송은 막지 못한다
- 추가 지연 — 발송 직전에 SMTP 왕복이 한 번 더 붙는다. 하루 100통 기준으로는 동시 6곳 확인으로 1분 안에 끝나지만, 발송량이 늘면 다시 재야 한다
측정 쪽 한계도 있다. 판정별 반송률은 무작위 배정이 아닌 관측 비교였고, 판별력은 소급 측정이다. 이후 손해사정 업종의 도달 가능성을 이 검사로 쟀을 때는 26개사 중 수신 서버가 ok로 답한 곳이 4개사(15%)였다. 나머지 회사가 unknown이었는지 reject였는지는 그 기록만으로 가를 수 없다. ok가 이렇게 드물다면 이 검사가 확답을 주는 범위가 업종에 따라 좁을 수 있다고 보고, 도달률 판단에는 다른 근거를 함께 쓴다.
이메일 반송률을 줄이려면 무엇부터 확인해야 하나
영업 메일이나 뉴스레터를 보내는 회사에서 이메일 반송률이 오르고 있다면, 대책을 고르기 전에 반송 주소를 지금 쓰는 검사의 판정별로 나눠 반송률부터 재 보길 권한다. 반송 건수가 아니라 판정별 반송 비율을 봐야 한다. 우리 경우 '공식 주소면 안전하다'는 직관이 비율을 재자 정반대로 나왔다.
그다음에는 게이트마다 무슨 질문에 답하는지 한 줄씩 적는다. 도메인이 살아 있나, 공식 주소인가, 그 계정이 지금 있나. 반송은 셋째 질문의 영역인데 우리는 앞의 두 질문만 하고 있었다. SMTP RCPT 확인을 직접 만든다면 5로 시작하는 거절을 전부 계정 없음으로 읽지 않는다. 응답 문구를 보고, 정책 차단이 섞이면 판정을 미룬다. 판정할 수 없는 주소는 통과시키는 편이 리드를 잃지 않는다.
발송할 주소를 어디서 어떻게 모으는지는 콜드메일 리드 이메일 수집 자동화 기록에, 클릭 뒤 문의까지의 전환을 따로 잰 과정은 콜드메일 회신율을 문의 수로 다시 잰 기록에 정리했다. 발송 전 주소 검증부터 전환 계측까지 영업 메일 파이프라인을 점검해야 한다면 상담에서 이야기를 나눌 수 있다.