엔지니어링

메일 반송 원인, 홈페이지에 적힌 주소가 죽은 메일함이었다

메일 반송 원인은 주소가 틀려서가 아니라, 홈페이지에 맞게 적힌 주소의 메일함이 이미 죽어 있어서였다. 공식 주소인지 확인하는 검사로는 반송이 줄지 않았고, 받는 서버에 계정 유무를 직접 묻고서야 반송 주소를 미리 가려낼 수 있었다.

2026-11-09결정 시점: 2026년 8월 4일, 다음 날 오전 9시 10분 정기 발송부터 적용출발 상태: 반송률 8.3%, 하루 발송 상한 100통 → 50통관측: 반송 40건 중 32건이 공식 주소 대조에서 신뢰도 '높음'으로 통과판정별 반송률: 검증 통과 174건 9.8% · 판단불가 128건 11.7% · 미등재 162건 4.9%기각한 안: 공식 주소만 보내면 대상 1,876곳 → 980곳(-48%), 반송 근거 없음조치: 발송 직전 SMTP RCPT 확인(응답 대기 15초·동시 6개)재측정(과거 주소 대상): 첫 판 57%/10% → 문구 분리 48%/2% → 재구성 48%/0%(수신거부 제외 60건)한계: 배포 뒤 실측 반송률은 기록에 없음, Outlook·Proofpoint 계열은 판정 불가

메일 반송 원인을 왜 다시 찾아야 했나?

메일 반송 원인은 주소가 틀려서가 아니라, 홈페이지에 맞게 적혀 있는 주소의 메일함이 이미 죽어 있어서였다. 그래서 '공식 주소인지' 확인하는 검사를 아무리 엄하게 걸어도 반송은 줄지 않았고, 받는 서버에 '그 계정이 지금 있느냐'를 직접 묻는 검사를 넣고서야 반송 주소를 미리 가려낼 수 있었다. 이 글은 그 결론에 닿기까지 세웠다가 버린 가설과, 측정을 잘못해서 숫자가 부풀었던 실수까지 순서대로 남긴 기록이다.

출발점은 하루 발송 상한이었다. 우리 발송 스크립트에는 반송률이 높아지면 하루에 보낼 수 있는 메일 수를 절반으로 깎는 규칙이 들어 있다. 2026년 8월 4일 기준 반송률은 8.3%였고, 이 규칙이 하루 상한을 100통에서 50통으로 줄여 놓고 있었다. 규칙 자체는 옳다. 반송이 쌓이면 받는 쪽 메일 서비스가 발송 도메인을 스팸 발송처로 의심하고, 그때부터는 멀쩡한 주소로 보낸 메일까지 받은편지함에 닿지 못한다.

문제는 이 상한이 영업 속도 전체를 붙잡는다는 점이었다. 하루 100통이 50통으로 줄면 영업 접점도 절반으로 준다. 제목이나 본문을 바꿔 반응을 비교하는 실험도 표본이 쌓이기까지 두 배를 기다려야 한다. 반송률은 메일 품질 지표 하나가 아니라, 상한 하나로 발송량·실험 속도·영업 기회를 한꺼번에 묶는 병목이었다.

반송과 처음 싸운 것도 아니었다. 2026년 7월 20일에 잰 반송률은 7.2%(125통 중 9통)로, 흔히 위험선으로 보는 5%를 이미 넘었다. 그때 반송 주소 대부분은 회사가 폐업했거나 도메인이 만료돼 DNS 자체가 사라진 경우였다. 그래서 발송 전에 도메인의 메일 수신 레코드를 조회하는 검사를 넣었다. 그런데 그 검사를 넣고도 8월 초 반송률은 8.3%였다. 남은 반송은 다른 곳에서 나오고 있었다.

처음 잰 숫자: 반송 40건 중 32건이 두 검사를 통과했다

당시 발송 전 방어는 두 겹이었다. 첫째 겹은 DNS 조회다. 받는 도메인에 메일 수신 레코드(MX, 없으면 A 레코드)가 있는지 4.0초 안에 확인하고, 확정적으로 없을 때만 발송 대상에서 뺀다. 조회가 실패하거나 시간이 넘으면 통과시킨다. 일시 장애 때문에 정상 주소를 영구히 버리는 손해가 반송 1건보다 크다고 봤기 때문이다.

둘째 겹은 공식 주소 대조다. 회사 홈페이지를 읽어, 보내려는 주소가 홈페이지에 적힌 공식 연락처와 같은지 맞춰 보고 판정과 신뢰도를 붙인다. 원래 목적은 엉뚱한 회사 받은편지함으로 메일이 가는 사고를 막는 일이었지만, 은연중에 '공식 주소면 살아 있는 주소'라고 기대하고 있었다.

측정은 단순하게 했다. 메일 발송 서비스가 돌려준 반송 주소 40건을 공식 주소 대조 결과와 주소 단위로 이어 붙였다. 결과는 40건 중 32건이 공식 주소로 등재돼 있었고, 신뢰도도 '높음'이었다. 도메인은 살아 있고 홈페이지에도 그 주소가 적혀 있는데, 실제로 보내면 받는 서버가 그런 계정이 없다고 답한 셈이다.

출발 상태 네 숫자. 반송률 8.3%, 하루 발송 상한 100통에서 50통으로 축소, 반송 40건 중 32건이 공식 주소 대조 통과, 공식 주소 대조가 판정을 내린 범위 46%
처음 잰 숫자: 반송 대부분이 기존 검사 두 겹을 모두 통과했다

홈페이지에 한 번 적힌 주소는 잘 고쳐지지 않는다. 담당자가 퇴사해 계정을 지웠거나 회사가 메일 서비스를 옮겼어도, 홈페이지 하단의 연락처 문구는 몇 년씩 그대로 남는다. 홈페이지에 박제된 주소는 DNS 조회도, 공식 주소 대조도 모두 통과한다. 두 검사 모두 '계정이 살아 있는가'는 묻지 않기 때문이다.

이 시점에 숫자 하나를 더 확인했다. 공식 주소 대조가 판정을 내릴 수 있는 범위는 전체 대상의 46%였다. 절반 넘는 대상에는 이 검사가 아무 말도 하지 못한다는 뜻이다. 이 숫자는 바로 다음 가설의 비용을 정하는 값이 됐다.

세운 가설: 공식 주소에만 보내면 반송이 줄지 않을까?

가장 먼저 떠오른 안은 공식 주소 대조를 참고 정보에서 차단 조건으로 올리는 것이었다. 홈페이지에서 공식 주소로 확인된 곳에만 보내고, 확인 못 한 주소는 발송 대상에서 아예 뺀다. 공식으로 확인한 주소가 확인 못 한 주소보다 살아 있을 확률이 높을 거라는 직관에 기댄 안이다.

홈페이지에서 공식 주소로 확인한 곳에만 보내면 반송률이 내려가고, 하루 상한도 다시 100통으로 돌아온다.

비용은 계산이 쉬웠다. 판정 범위가 46%뿐이라, 이 조건을 걸면 발송 대상이 1,876곳에서 980곳으로 줄어든다. 48%가 한 번에 빠진다. 그래도 처음에는 감수할 만하다고 봤다. 대상이 절반이 돼도 반송률이 내려가 상한이 100통으로 돌아오면, 하루 실제 발송량은 크게 줄지 않는다는 계산이었다.

다만 앞의 '40건 중 32건'이라는 관측이 이미 이 가설을 의심하라고 말하고 있었다. 반송 주소 대부분이 공식 주소였다는 사실은, 공식 주소라는 표시가 반송을 막아 주지 않는다는 신호일 수 있다. 하지만 반송 쪽만 본 숫자에는 분모가 없다. 보낸 주소 대부분이 애초에 공식 주소였다면, 반송도 공식 주소에서 많이 나오는 게 당연하다. 그래서 차단 조건을 걸기 전에 판정별 반송률을 먼저 쟀다.

가설이 틀린 지점: 검증 통과 주소가 2배 더 반송했다

판정별 반송률은 발송 이력과 공식 주소 대조 결과를 판정 값으로 묶어 계산했다. 각 판정에 속한 주소 수를 분모로, 그중 반송된 주소 수를 분자로 놓았다. 결과는 가설과 정반대였다.

공식 주소 대조 판정별 실제 반송률 막대 그래프. 검증 통과 174건 9.8%, 판단불가 128건 11.7%, 미등재 162건 4.9%
판정별 반송률: 미등재 주소가 가장 적게 반송했다
가설이 틀린 지점: 검증 통과 주소가 2배 더 반송했다
공식 주소 대조 판정주소 수실제 반송률
검증 통과174건9.8%
판단불가128건11.7%
미등재162건4.9%

공식 주소로 검증을 통과한 174건의 반송률은 9.8%였다. 판단불가 128건은 11.7%였고, 홈페이지에서 아예 찾지 못한 미등재 162건이 4.9%로 가장 낮았다. 검증 통과군이 미등재군보다 2배 더 반송했다. 이 상태에서 공식 주소만 보내기로 했다면, 대상을 1,876곳에서 980곳으로 반토막 내면서 반송률은 오히려 오르는 쪽으로 갔을 수도 있다.

한 가지는 짚어 둔다. 이 비교는 관측 자료라 무작위로 나눈 실험이 아니다. 판정별로 업종이나 회사 규모가 다를 수 있고, 그 차이가 반송률 차이를 일부 설명할 수도 있다. 하지만 차단 조건의 근거가 되려면 적어도 검증 통과군이 덜 반송해야 했다. 방향이 반대로 나온 이상, 이 안을 밀 근거는 남지 않았다. 그래서 공식 주소 대조를 차단 조건으로 올리는 안은 기각했다.

진짜 원인은 무엇이었나: '공식 주소'와 '살아 있는 메일함'은 다른 질문이다

돌아보면 답은 검사의 질문 자체에 있었다. 공식 주소 대조는 '이 주소가 이 회사의 공식 연락처인가'를 묻는다. 반송은 '이 메일함이 지금 메일을 받는가'의 문제다. 두 질문은 겹쳐 보이지만, 오래된 홈페이지에서는 정확히 반대로 움직일 수 있다. 홈페이지에 오래 적혀 있던 주소일수록 공식 주소 대조는 확신을 높이는데, 그 메일함이 정리됐을 가능성도 함께 커진다.

DNS 조회도 같은 한계를 갖는다. DNS는 도메인이 살아 있는지만 알려 준다. 회사가 영업 중이고 도메인 비용을 계속 내면 MX 레코드는 남아 있다. 그 도메인 아래 개별 계정이 지워졌는지는 DNS에서 보이지 않는다. 기존 두 겹은 모두 '도메인과 회사' 수준을 봤고, 반송은 '계정' 수준에서 나고 있었다.

그러면 계정 수준의 질문을 누구에게 해야 하나. 답을 아는 쪽은 받는 메일 서버 하나뿐이다. 메일을 보낼 때 발송 서버는 받는 서버에 '이 주소로 보낼 메일이 있다'고 먼저 알리는데, 이 단계가 SMTP의 RCPT TO 명령이다. 계정이 없으면 받는 서버는 이 단계에서 거절 응답을 돌려준다. 실제 반송도 대부분 이 응답에서 시작한다.

조치: 발송 직전에 받는 서버에게 계정 유무를 묻는다

그래서 DNS 조회 뒤, 실제 발송 직전에 셋째 검사를 넣었다. 받는 도메인의 MX 서버로 25번 포트에 접속해 인사(EHLO), 보내는 주소(MAIL FROM), 받는 주소(RCPT TO)까지만 말하고 끊는다. 본문을 보내는 DATA 단계로 가지 않으므로 메일은 나가지 않는다. 받는 서버가 RCPT 단계에서 뭐라고 답하는지만 본다.

발송 직전 주소 검사 3단 흐름도. DNS 조회, 공식 주소 대조, SMTP RCPT 확인 순서이며, RCPT 단계에서 계정 없음을 명시한 5xx만 제외하고 나머지는 발송
발송 직전 주소 검사 3단: 셋째 층만 계정 수준을 본다

설정값은 하루 상한에 맞췄다. 수신 서버 응답은 최대 15초 기다리고, 넘으면 판정 불가로 통과시킨다. 동시에 6개 주소를 확인한다. 하루 상한이 100통 이하라 이 정도면 1분 안에 끝난다. 실제 발송은 메일 발송 서비스(Resend)를 거치고 각 발송 사이에 3초 간격을 두므로, 확인 시간이 발송 일정을 밀어내지 않는다.

검사 순서에도 이유가 있다. DNS 조회가 먼저 죽은 도메인을 빼 주므로, RCPT 확인은 메일 서버가 살아 있는 도메인에만 접속한다. 반대로 RCPT 확인을 먼저 돌리면 없는 도메인마다 접속을 시도하다 시간 초과를 기다리게 된다. 값싼 검사를 앞에, 비싼 검사를 뒤에 둔 셈이다. 공식 주소 대조는 셋째 검사와 별개로 그대로 남겨 두었다. 이 검사는 반송을 막지는 못해도, 엉뚱한 회사 받은편지함으로 메일이 가는 사고를 막는 원래 역할은 여전히 한다.

판정은 셋으로 나눴다. 계정 부재를 명시한 5xx 응답이면 '거절'로 보고 발송 대상에서 뺀다. 2xx·3xx면 '정상'으로 보내고, 4xx·접속 실패·시간 초과는 '판정 불가'로 역시 보낸다. 판정 불가를 통과시키는 이유는 DNS 조회와 같다. 확인을 못 했다는 이유로 정상 주소를 버리지 않는다. 또 일부 서버는 없는 주소에도 정상 응답을 주므로, '정상'은 계정 존재의 증명이 아니라 '거절당하지 않았다'는 뜻일 뿐이다.

유료 이메일 검증 API도 대안으로 올렸지만 기각했다. 매달 고정비가 새로 생기는데, 결국 그 서비스들이 보는 신호도 같은 RCPT 응답이라 직접 물어도 같은 신호를 얻는다고 판단했다. 메일 제목 표기를 바꿔 스팸 필터를 피해 보자는 안도 나왔지만, 제목 맨 앞의 '(광고)'는 정보통신망법 §50④가 정한 법정 표기라 임의로 바꿀 수 없어 기각했다.

측정이 틀렸던 곳: 550 5.7.1을 계정 없음으로 읽었다

첫 판 분류기는 단순했다. 5xx면 전부 계정 없음으로 봤다. 과거에 반송된 주소(반송군)와 반송되지 않은 주소(대조군)에 이 검사를 돌려 보니, 반송군의 57%를 걸러 냈고 대조군도 10%를 걸렀다. 거르는 비율이 높아 처음에는 꽤 쓸 만해 보였다.

대조군 10%를 하나씩 열어 보다가 이상한 주소를 찾았다. 우리에게 실제로 회신까지 보낸 살아 있는 리드 bd_korea@bd.com이 '550 5.7.1 blocked using Spamhaus'로 거절돼 있었다. 이 응답은 계정이 없다는 뜻이 아니었다. 확인하러 접속한 우리 쪽 IP가 차단 목록(Spamhaus)에 올라 있어서 받는 서버가 대화를 거부했다는 뜻이다. 확인 검사를 돌린 PC가 가정용 인터넷 회선이었고, 가정용 IP는 이런 목록에 흔히 올라 있다.

즉 첫 판의 57%와 10%는 양쪽 다 부풀려진 숫자였다. 반송군에서도 정책 차단으로 걸린 주소가 '계정 없음'으로 섞여 들어갔고, 대조군에서는 멀쩡한 주소가 같은 이유로 잘려 나갔다. 이대로 배포했다면 회신까지 준 고객 후보를 영구히 버리는 검사가 됐을 것이다. 거르는 비율이 높다고 좋은 분류기가 아니었다.

RCPT 응답 분류기 코드. 계정 부재 문구가 있고 정책 차단 문구가 없는 5xx만 reject로 판정한다
5xx를 숫자가 아니라 응답 문구로 가른다

그래서 분류를 응답 코드가 아니라 응답 문구로 바꿨다. 'unknown user', 'no such user', '5.1.1' 같은 계정 부재 문구가 있고, 동시에 'spamhaus', 'blocked', 'policy', '5.7.' 같은 정책 차단 문구가 없을 때만 거절로 본다. 두 문구가 함께 나오면 계정 유무를 알 수 없으니 판정 불가로 통과시킨다. 정책 차단 응답 자체는 SMTP 550 5.7.1 거절을 계정 없음으로 읽으면 생기는 일에 따로 정리해 두었다.

이 실수를 잡은 건 숫자가 아니라 대조군의 개별 주소였다. 대조군 오차단 10%를 '조금 있는 오차' 정도로 넘겼다면 이 주소를 열어 볼 일도 없었다. 분류기를 평가할 때는 비율만 보지 말고, 잘못 걸린 주소를 몇 개라도 직접 열어 응답 문구를 읽어 봐야 한다. 이번에는 회신까지 준 리드 한 명이 그 역할을 했다.

같은 실수를 다시 하지 않도록 회귀 테스트를 붙였다. 테스트 케이스는 9개이고, 전부 실제로 받은 응답 문구를 그대로 넣었다. 지어낸 문구로 만든 테스트는 정규식이 실제 서버 문구를 놓치는 경우를 잡지 못하기 때문이다.

재측정 결과: 반송 주소 48%를 걸렀고 정상 주소 오차단은 0%

문구 기반으로 바꾼 분류기를 같은 반송군·대조군에 다시 돌렸다. 대조군은 수신거부 주소를 뺀 60건 기준으로 쟀다. 정책 차단을 분리하자 판별력은 반송군 48% 차단, 대조군 2% 오차단으로 바뀌었고, 분류기를 재구성한 뒤에는 대조군 오차단이 0%가 됐다.

분류기 판별력 세 단계 비교. 첫 판 반송군 57% 대조군 10%, 문구 분리 후 48%와 2%, 재구성 후 48%와 0%
분류기 판별력 재측정: 숫자는 줄었지만 정확해졌다
재측정 결과: 반송 주소 48%를 걸렀고 정상 주소 오차단은 0%
분류기 단계반송군 차단대조군 오차단해석
첫 판 (5xx 전부 거절)57%10%정책 차단이 양쪽에 섞여 부풀었다
정책 차단 문구 분리48%2%계정 부재만 남겼다
재구성 후48%0%수신거부 제외 대조군 60건 기준

반송군 차단률은 57%에서 48%로 내려갔다. 숫자만 보면 나빠졌지만, 빠진 9%포인트는 원래 계정 부재가 아니었던 주소다. 반대로 대조군 오차단은 10%에서 0%로 내려갔다. 발송 검사에서 더 비싼 실수는 살아 있는 주소를 버리는 쪽이다. 반송 1건은 평판에 흠을 내지만, 버린 리드는 다시 돌아오지 않는다.

셋째 검사의 장점은 공식 주소 대조의 판정 범위와 상관없이 작동한다는 점이다. 공식 주소 대조는 대상의 46%에만 판정을 내렸지만, RCPT 확인은 MX 서버에 접속할 수 있는 모든 주소에 질문을 던진다. 그래서 발송 대상을 1,876곳에서 980곳으로 깎지 않고도 반송 주소를 미리 뺄 수 있다.

이 결과를 바탕으로 반송률이 8.3%에서 4%대로 내려가고 하루 상한이 50통에서 100통으로 돌아올 것으로 예상했다. 2026년 8월 4일에 변경을 반영했고, 다음 날 오전 9시 10분 정기 발송부터 적용했다. 다만 이 기록을 쓰는 근거 자료에는 배포 뒤 실제 반송률이 남아 있지 않다. 위의 48%와 0%는 과거 주소에 다시 돌린 결과이고, 4%대는 예측이다. 이 둘을 실측 개선율로 바꿔 말하지 않는다.

남는 한계: 확인하러 간 우리 IP가 막히는 곳은 여전히 못 본다

가장 큰 한계는 커버리지다. 확인 검사를 돌리는 PC의 가정용 IP가 Spamhaus에 올라 있어서, Outlook·Proofpoint 계열 메일 서버는 RCPT 단계에서 5.7.1 정책 거부를 돌려준다. 분류기는 이 응답을 판정 불가로 통과시키므로, 이 계열 도메인에는 셋째 검사가 아예 걸리지 않는다. 오차단을 0%로 만든 설계가 그 대가로 일부 도메인을 구조적으로 못 보게 만든 셈이다. 실제 발송은 발송 서비스의 IP로 나가므로, 이 차단은 확인 단계에만 영향을 준다.

둘째, 판정 불가가 많은 환경에서는 검사가 시간만 쓴다. 일부 클라우드나 인터넷 회선은 25번 포트를 막아 둔다. 그런 곳에서 돌리면 모든 주소가 판정 불가로 나와 아무것도 거르지 못한다. 그래서 환경 변수 하나로 이 검사를 통째로 건너뛸 수 있게 해 두었다. 셋째, 없는 주소에도 정상 응답을 주는 서버는 이 방식으로 판별할 수 없다.

넷째, 발송 직전에 SMTP 왕복이 하나 더 생긴다. 하루 상한 100통 기준 동시 6개로 1분 안에 끝나지만, 상한을 크게 올리면 이 시간도 함께 늘어난다. 마지막으로, 판정별 반송률 비교는 관측 자료라 인과를 증명하지 못한다. '공식 주소 대조가 반송을 예측하지 못한다'는 결론까지는 말할 수 있지만, '공식 주소가 반송을 일으킨다'고는 말할 수 없다.

  • 커버리지: Outlook·Proofpoint 계열은 5.7.1 정책 거부로 항상 판정 불가
  • 환경 의존: 25번 포트가 막힌 곳에서는 전 건 판정 불가
  • 전부 받는 서버: 없는 주소에도 정상 응답을 주면 판별 불가
  • 시간: 하루 100통 기준 동시 6개로 1분, 상한을 올리면 같이 늘어난다
  • 근거: 배포 뒤 실측 반송률은 아직 기록에 없다

비슷한 상황이라면 무엇부터 재야 하나?

콜드메일이나 뉴스레터를 보내다 반송률 때문에 발송량이 묶였다면, 주소를 거르는 검사를 하나 더 만들기 전에 지금 검사의 판정별 반송률부터 재 보길 권한다. 반송 주소만 보지 말고, 판정마다 분모를 놓고 반송률을 비교해야 한다. 우리처럼 '검증 통과'가 더 많이 반송하는 결과가 나오면, 그 검사는 반송을 막는 장치가 아니라 다른 질문에 답하는 장치다.

받는 서버에 직접 묻는 방법을 쓴다면, 5xx를 숫자로만 읽지 말고 응답 문구를 갈라야 한다. 특히 확인을 돌리는 곳의 IP 평판을 먼저 확인하고, 정책 차단 응답은 판정 불가로 둬야 살아 있는 리드를 버리지 않는다. 반송률 숫자와 검사 구조를 함께 본 다른 기록은 이메일 반송률과 SMTP RCPT 확인에 있다. 영업 메일 발송이나 업무 자동화 구조를 점검하고 싶다면 상담으로 문의할 수 있다.

같은 방식으로 우리 업무를 재보고 싶다면

이 글에 쓴 계측·판정·자동화는 저희가 실제로 매일 돌리는 방식 그대로입니다. 어떤 작업을 자동화할 수 있고 어디를 사람이 잡아야 하는지, 현재 업무 흐름을 놓고 같이 짚어 드립니다.

새 글이 올라오면 알려 드립니다

이런 계측 기록을 새로 쓰면 메일로 한 통 보냅니다. 광고나 판촉은 보내지 않습니다.