Rinda Sequence Email Worker의 MillionVerifier 검증 파이프라인 분석 + 2026년 Gmail·Naver 등 프로바이더의 기술적 대응 + 정확도 한계의 실측 수치와 커뮤니티 논쟁 정리
250 OK(accept-all 유사), Gmail은 rate-limit·IP 평판으로 프로빙을 차단한다. Naver는 예외(catch-all 아님, 핸드셰이크 가능하나 해외 IP throttling이 장벽).결론부터: MillionVerifier를 포함한 검증 cascade가 발송 파이프라인에 완전히 통합되어 있고 항상 활성이다.
워커는 processor.ts:55-67에서 6단계로 발송을 오케스트레이션하며, 검증은 발송 직전 Step 2에 위치한다.
Pre-Step(제한) → Step 0(상태) → Step 1(리드+bounce) →
▶ Step 2(검증, 6-gate) ◀ → Step 3(콘텐츠) → Step 4+5(발송)
Tier 0(무료) 게이트 5개를 모두 통과한 뒤, Tier 2(유료) MillionVerifier cascade를 거쳐야 발송된다.
VERIFY_PREFLIGHT_ROLE_BLOCK=true)Tier 0DISPOSABLE_BLOCK=true)Tier 0발송 시점(caller: "send_time")에는 비용 최적화를 위해 maxTier=1 (MV 단일 신호)로 동작한다. 백그라운드 enrich 시에는 전체 cascade가 돈다.
| Tier | Provider | 역할 | 판정 → 동작 |
|---|---|---|---|
| 1 | MillionVerifier | 저비용 1차 — ev:캐시·bounce·MX 선검사 후 API | deliverable+score≥70 → send / invalid → block / unknown·accept_all → escalate |
| 2 | Findymail | MV 판정 불가 시만 호출 | 2-of-2 negative → block / valid → send |
| 3 | Hunter | Findymail도 불가 시만 | valid≥80 → send / 3사 모두 불가 → block (fail-CLOSED) |
verdict="send" → 발송 진행verdict="block" / "inconclusive" → Step skip (sequence_step_executions.status="skipped", enrollment는 유지)CreditsExhaustedError → fail-OPEN (크레딧 고갈 시엔 발송 진행 — 워커 보호)| 레이어 | 저장소 / TTL | 역할 |
|---|---|---|
검증 캐시 ev: | Redis · 50년 (bounce webhook으로 invalidate) | 중복 검증 회피, 대부분 여기서 종료 |
Bounce 블랙리스트 bounce:bl | Redis SSOT | 발송 전 이미 bounced된 주소 원천 차단 |
MX 캐시 mx:v1 | Redis · 24h/1h | DNS MX 조회 결과 캐시 |
| 사후 webhook | SES/SendGrid → onBounceDetected() | bounce 수신 시 blacklist 추가 + 검증 캐시 무효화(stale "ok" 방지) |
lead-details.ts:42-123 — lead_contacts.verification_status enum이 SSOT다. "failed"·"inconclusive"는 발송 후보에서 원천 제외(Step 1 필터).
| status | 의미 | 발송 |
|---|---|---|
legacy | 검증 이전 구 이메일 | — |
unverified | 신규, 미검증 | 발송 시 검증 |
verified | cascade verdict=send | ✅ 적격 |
failed | 어떤 API가 명확히 부정 (resolvedAtTier 존재) | ❌ 제외 |
inconclusive | 3사 모두 판정 불가 (resolvedAtTier=null) | ❌ 제외 |
workers/bullmq/sequence-email-worker/steps/verify-email/ (gates·pipeline), services/verification-cascade.service.ts (3-tier), services/million-verifier.service.ts (MV API + 한국 도메인 보정), services/bounce-check.service.ts (Redis bounce SSOT).
한국 도메인 보정 — .kr/.한국 도메인은 MV 결과를 risky로 완화 처리하는 로직이 있다. 이는 아래 §3에서 다루는 "국제 검증기가 한국 프로바이더에 약하다"는 구조적 한계를 코드 레벨에서 인지하고 보완한 것이다.
검증은 퍼널(funnel) 구조다. 각 레이어가 무엇을 잡고 무엇을 못 잡는지가 정확도 한계를 결정한다.
| 레이어 | 동작 | 잡는 것 | 못 잡는 것 |
|---|---|---|---|
| 1. Syntax (RFC 5322) | 허용 문자·@·도메인 형식 | @ 누락, 연속 점, 공백 | 실재 여부 — 형식만 확인 |
| 2. Domain/MX | 도메인 존재 + MX 레코드 발행 | 죽은·비메일 도메인 | mailbox 존재, 실제 도달 (MX 있음 ≠ 도달) |
| 3. SMTP handshake (RCPT TO) | 포트 25 → HELO → MAIL FROM → RCPT TO 후 DATA 전 중단. 250=수락, 550=거부 | 표준 도메인 mailbox 존재 | catch-all, Gmail/Yahoo 무차별 250, greylisting(4xx→unknown) |
| 4. Catch-all 탐지 | 가짜 랜덤 주소로 2차 프로빙 → 가짜도 250이면 catch-all | 도메인이 accept-all인지 | 그 안의 개별 mailbox 실재 (해소 불가) |
| 5. Role-based | info@·admin@ prefix DB 매칭 | role 주소 분류 | deliverability와 무관 |
| 6. Disposable | 임시메일 도메인 DB(500+) 매칭 | 인식된 임시 제공자 | 신규/미인식 disposable |
| 7. Spam-trap | 무참여·수집출처 패턴 간접 추정 | recycled/typo trap 일부 | pristine trap은 발송 없이 사실상 탐지 불가 |
SMTP 프로빙 = directory harvest attack과 동일하게 보인다. 자체 서버로 대규모 프로빙 시 DNSBL 블랙리스트에 등재될 수 있다. RFC 2505는 VRFY 비활성화를 권고한다. 그래서 검증 벤더들은 점점 SMTP 핸드셰이크 대신 캐시·행동 데이터로 이동 중이다.
ISP는 trap 목록을 절대 공개·공유하지 않는다. ZeroBounce의 "99.6% spam-trap 탐지" 같은 광고는 메커니즘 미공개이며, "검증기는 spam-trap을 확인·제거할 수 없다"는 독립 진술과 모순된다.
참고: NeverBounce · Kickbox · BriteVerify는 모두 Validity 소유다(별개 마케팅, 같은 모회사) — 벤더 "비교"의 독립성을 해석할 때 유의.
대형 프로바이더는 SMTP 검증을 점점 무력화한다. 검증기가 "valid"라 해도 그 응답이 사실이 아닐 수 있다.
| 프로바이더 | 주 대응 | 정직한 RCPT? | 비고 |
|---|---|---|---|
| Microsoft 365 / Exchange Online | RCPT에서 기본 250 OK → DATA 뒤 검증. 거부기능(DBEB) opt-in이라 대부분 미활성 | 아니오 (accept-all 유사) | 단일 IP는 수 시간 내 "항상 250"으로 degrade. B2B mailbox의 50~70% 차지 → 영향 막대 |
| Gmail / Google Workspace | 정직 응답 대신 rate-limit + IP 평판 차단 (421 4.7.0, 550 5.7.1) | 부분 — 프로빙 시 degrade | 공개 한도보다 훨씬 낮게 행동 차단. 일부 벤더는 SMTP 대신 우회법(People Chip 등) 사용 |
| Yahoo | 없는 mailbox에도 250 OK (의도적 anti-probing). non-bounce는 silent하게 스팸 라우팅 | 아니오 (설계상 accept-all) | gibberish 주소가 250이면 그 세션 전체를 "unknown" 처리 권장 |
| Naver (네이버메일) | catch-all 아님, MX 활성, SMTP responsive → 핸드셰이크 검증 가능 | 예 (throttle 안 걸리면) | 주 장벽은 국제 발신 IP rate-limiting — 한국 평판 없는 해외 발신자에 공격적 제한 |
| Daum/Hanmail · Kakao | 2022.09 이후 해외 발신 메일 필터링·silent drop. 해외 IP defer, 점진 warm-up 요구 | 해외 IP throttled | SPF/DKIM·UTF-8 필수 |
SMTP는 서버가 임의·거짓 응답을 줄 수 있고, catch-all은 항상 250이다. 검증은 원천적으로 불완전하다.
| 벤더 | 광고 | 벤더 | 광고 |
|---|---|---|---|
| NeverBounce | 99.9% | Bouncer | 98% |
| ZeroBounce | 99% / 99.6% | DeBounce | 97%+ |
| MillionVerifier | 99%+ | Emailable | 96% |
| Verifalia | 99% | Kickbox | 95% |
| LeadMagic | 99.5% | Apollo | 91% |
| 순위 | 도구 | 실측 정확도 |
|---|---|---|
| 1 | Hunter | 70.00% |
| 2 | Clearout | 68.37% |
| 3 | Kickbox | 67.53% |
| 4 | Bouncer | 65.43% |
75%를 넘은 도구가 하나도 없다. 격차 원인은 catch-all, greylisting, 엔터프라이즈 메일서버의 anti-testing 필터.
| 벤더 | 정확도 | catch-all 해소 | 오탐(FP) | 미탐(FN) |
|---|---|---|---|---|
| LeadMagic | 99.5% | 94.2% | 0.3% | 0.2% |
| ZeroBounce | 97.8% | 12% | 0.9% | 1.3% |
| NeverBounce | 96.9% | 8% | 1.4% | 1.7% |
| Bouncer | 96.5% | 15% | 1.2% | 2.3% |
| MillionVerifier | 95.8% | 5% | 1.8% | 2.4% |
| Kickbox | 95.2% | 10% | 2.1% | 2.7% |
| Emailable | 94.6% | 7% | 2.4% | 3.0% |
| BriteVerify | 93.4% | 9% | 3.1% | 3.5% |
주류 검증기는 catch-all의 5~15%만 해소하고 나머지 85~95%는 unknown/risky로 반환한다. (우리가 쓰는) MillionVerifier는 이 테스트에서 catch-all 5%만 해소 — 99% 광고와 모순. 그래서 코드의 한국 도메인 보정·fail-CLOSED 정책이 의미가 있다.
| 추정치 | 모집단 | 출처 |
|---|---|---|
| 8.6~15% | 일반/평균 리스트 | Bulk Email Checker 2026 |
| 20~30% | B2B 도메인 | Bulk Email Checker 2026 |
| 28% | 실제 outbound (10K) | LeadMagic 2026 |
| ~38% | 2,572 주소 분석 | Hunter 2024/25 |
| 40~60% | B2B 이메일 | Enrichley 2026 |
"99% 정확"은 깨끗한 일반 주소(Gmail 개인 등 표준 mailbox) 기준일 때만 현실적이다. 혼합 B2B 콜드 리스트에서는 65~75%가 현실이며, 리스트의 1/4은 어떤 도구를 써도 unknown/risky로 남는다. 100%는 SMTP·catch-all·프로바이더 무력화라는 구조적 이유로 불가능하다.
| ESP | 입장 |
|---|---|
| SendGrid/Twilio | 검증 판매하나 Pro/Premier 유료 티어 한정 |
| Mailgun | 자사 데이터가 SMTP보다 우수 주장. 단 검증 결과가 실제 발송을 막지 않음 |
| Klaviyo | 자체 검증 없음(외주). 자체 권장은 double opt-in |
| Postmark | 블록리스팅은 미동의·오래된 주소(trap) 탓 → 검증보다 동의/예방 우선 |
SMTP 검증이 catch-all·대형 프로바이더에서 "중립화"되어 unknown/accept-all만 반환한다는 비판에 대해, 벤더들의 반응은 2세대 카테고리 등장이다 — BounceBan/Allegrow/Instantly/Bouncer가 "프로빙 대신 도메인 행동 분석·네트워크 패턴·identity matching"을 내세운다. 이는 곧 plain SMTP 검증의 실패를 사실상 인정한 셈.
"Valid" ≠ "Safe to Send." 60일 넘은 리스트는 재검증한다(B2B 리스트 연 ~28% 감소). catch-all "valid"는 발송하되 비율을 2~5%로 캡.
| 단계 | 조치 | 임계값/수치 |
|---|---|---|
| 1. 수집 게이트 | double opt-in + CAPTCHA | 확인 구독자 open률 30~40%↑ |
| 2. 사전 검증 | 검증하되 accept-all/Gmail "valid" 불신, catch-all 2~5% 캡, 60일+ 재검증 | — |
| 3. 바운스 자동화 | 하드 바운스·스팸불만 즉시 영구 suppression; 소프트는 3~5회 재시도 | 하드 ≈ 전체 바운스의 80% |
| 4. Engagement sunset | 90일 무참여 → 재참여 캠페인 후 제거 | 일간 발신=3주, 주간=2개월 |
| 5. 평판 모니터링 | bounce·complaint 상시 감시 | 아래 표 |
| 지표 | 권장 | 경고/조치 |
|---|---|---|
| AWS SES 바운스(하드만) | <5% | ≥5% 자동 review, ≥10% 발송 중단 가능 |
| AWS SES 불만 | <0.1% | ≥0.1% review, ≥0.5% 중단 가능 |
| 범용 바운스 | <2% | 2~5% 주의, >5% 비상 |
| Google 2024 bulk-sender 스팸율 | <0.1% | >0.3% 차단 위험. SPF+DKIM+DMARC·one-click unsubscribe 필수 |
Word to the Wise(deliverability canonical): 검증은 증상 치료지 병 치료가 아니다. spam-trap 제거는 "타인에게 가는 메일"을 못 고친다 — trap이 있으면 미동의 수신자도 있다는 indicator일 뿐. 수집·동의·engagement가 검증보다 근본 신호이며, 검증은 "도달은 되지만 무참여"인 주소를 탐지하지 못한다 — 이것이 실제 스팸함 배치·블록리스팅을 일으킨다.
현재 fail-CLOSED + 한국 도메인 보정 + bounce webhook invalidate 구조는 업계 베스트프랙티스에 부합한다. 추가로 고려할 것: ① catch-all "verified"의 실제 바운스율을 별도 모니터링(코드는 verified로 잡지만 27배 위험), ② 60일+ verified 재검증 cadence, ③ Naver/Daum 등 한국 프로바이더 발송 IP 평판 warmup (해외 IP throttling 회피).