BlueByte
5.7.26Fixed

Gmail이 550-5.7.26으로 거부: 도메인의 DMARC 정책 때문에 인증되지 않은 메일이 수신 거부됨

작성 Haneul Seo2026년 9월 25일 업데이트14 min

안녕하세요, BlueByte입니다. 지난주까지 잘 나가던 애플리케이션 메일이 Gmail에서 550 5.7.26 Unauthenticated email from example.com is not accepted due to domain's DMARC policy.로 되돌아옵니다. 사내 메일은 그대로 흐르니 메일 서버가 고장 난 것은 아닙니다 — Gmail이 우리 도메인이 게시한 정책을 그대로 집행하고 있는 것입니다. 오늘은 메시지 변형, Gmail이 수신 전에 무엇을 확인하는지, 어느 검사가 실패했는지 헤더와 DNS로 찾는 법, 원인별 해결, 그리고 나중에 DMARC를 조이면서도 우리 메일이 튕기지 않게 하는 순서까지 하나씩 짚어보겠습니다.

바운스 문구와, 뜻이 전혀 다른 변형 하나

여기서 나타나는 문자열은 둘이고, 같은 문제가 아닙니다. 첫 번째는 이것입니다:

550 5.7.26 Unauthenticated email from example.com is not accepted due to
domain's DMARC policy.

Google은 이 문장을 발신 메시지가 DMARC를 통과하지 못했을 때 받는 바운스로 문서화하고 있습니다. 우리 메일 서버는 보통 이를 전송 상태 보고서로 감싸고, 바운스 뒤에 도메인 관리자에게 문의하라는 문장이 이어지는 경우가 많습니다. 주변 문구는 중계 경로에 따라 달라집니다.

우리 도메인이 DMARC 정책을 게시했고, 메시지가 DMARC를 통과하지 못했으며, Gmail은 그 정책이 요청한 대로 처리했습니다. 두 번째 변형은 This email has been blocked because the sender is unauthenticated. Gmail requires all senders to authenticate with either SPF or DKIM.입니다. 이쪽은 우리 정책과 무관합니다 — 메시지에 쓸 만한 인증이 아예 없었고, _dmarc 레코드 유무와 상관없이 Gmail의 기본 발신자 요구사항에서 거부된 것입니다. 어느 문장을 받았는지 먼저 읽어 두면 엉뚱한 곳을 한 시간 뒤지는 일을 피할 수 있습니다.

Gmail이 메일을 받아들이기 전에 확인하는 것

2024년 2월 1일부터 Google은 모든 발신자에게 발신 도메인의 SPF 또는 DKIM 설정, 0.3% 미만의 스팸 신고율, 메일 전송 시 TLS 연결 사용, 발신 도메인·IP의 유효한 정방향·역방향 DNS 레코드, 그리고 주소 하나를 담은 단일 From: 헤더를 갖춘 RFC 5322 형식을 요구합니다. Gmail 계정으로 하루 5,000통을 넘겨 보내는 발신자에게는 요구사항이 더 붙습니다. SPF와 DKIM과 DMARC를 모두 갖추고, From: 헤더의 도메인이 SPF 도메인이나 DKIM 도메인 중 하나와 정렬되어야 하며, 마케팅·구독 메일에는 원클릭 수신거부가 있어야 합니다.

사람들을 가장 놀라게 하는 부분이 정렬(alignment)입니다. SPF를 깨끗이 통과하고도 DMARC에서 실패할 수 있습니다. SPF는 봉투 발신자, 즉 Return-Path가 되는 MAIL FROM을 검증하는 반면 DMARC는 header From: 도메인을 실제로 통과한 도메인과 비교하기 때문입니다. Return-Path를 자기 바운스 도메인으로 바꿔 쓰는 업체를 경유하면 SPF는 그 업체 기준으로 통과하고, 우리 쪽과는 아무것도 정렬되지 않습니다.

Authentication-Results 헤더로 어느 검사가 실패했는지 읽기

같은 경로로 우리가 통제하는 Gmail 계정에 테스트 메일을 한 통 보냅니다. p=quarantine이면 스팸함에 들어가고 헤더는 그대로 읽을 수 있습니다. p=reject라면 집행이 걸리지 않은 테스트 도메인이나 집계 보고서를 대신 써야 합니다. 메시지를 열고 원본 보기를 선택해 헤더 블록 위쪽을 읽습니다. 필드 순서와 괄호 안 설명은 수신 측에 따라 달라지므로, 형태를 맞추기보다 값을 읽으세요:

Authentication-Results: mx.google.com;
       spf=pass (google.com: domain of bounces@vendor.example designates
           198.51.100.20 as permitted sender) smtp.mailfrom=bounces@vendor.example;
       dkim=fail (body hash did not verify) header.i=@example.com;
       dmarc=fail (p=REJECT sp=REJECT dis=REJECT) header.from=example.com

한 줄씩 읽습니다. SPF는 통과했지만 header.from 도메인이 아니라 vendor.example 기준입니다. DKIM은 서명이 있었고 body hash에서 실패했습니다. 정렬된 것이 없으니 dmarc=fail이고, dis=REJECT가 Gmail이 실제로 적용한 처분을 기록합니다. 원문 그대로 읽기가 부담스럽다면 Google Admin Toolbox의 Messageheader 도구가 대신 파싱해 줍니다.

세 개의 DNS 레코드를 직접 조회하기

헤더는 어느 검사가 실패했는지 말해 주고, DNS는 왜인지를 말해 줍니다. 수신자가 보는 것과 같게 보려면 사내 네트워크 바깥에서 세 번 조회합니다:

dig +short TXT example.com
dig +short TXT _dmarc.example.com
dig +short TXT selector1._domainkey.example.com
"v=spf1 include:_spf.google.com include:mail.vendor.example ~all"
"v=DMARC1; p=reject; rua=mailto:dmarc@example.com; adkim=s; aspf=s"
"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..."

방금 읽은 헤더와 대조해 세 가지를 확인합니다. 발신 서비스가 SPF 레코드에 들어는 있습니까? 서명기가 쓰는 DKIM selector가 실제로 해석됩니까 — 게시된 키가 없는 selector를 가리키는 서명은 서명이 아무리 정확해도 검증될 수 없습니다. 그리고 adkim·aspf가 s로 되어 있습니까? 엄격 정렬을 요구해 relaxed 모드라면 받아들였을 하위 도메인 일치를 거부하는 설정입니다. _dmarc 응답이 비어 있다면 정책 변형은 배제되고, 기본 인증 바운스 쪽으로 돌아가게 됩니다.

헤더가 지목한 원인을 고치기

원인 셋, 해결 셋입니다:

  • 발신 출처가 인가되지 않음. 사용 중인 모든 발신 IP와 도메인이 SPF 레코드에 들어 있는지 확인한 뒤 다시 보냅니다. 업체나 새 앱 서버, 이전한 릴레이를 추가하면서 DNS를 아무도 손대지 않았을 때 나오는 전형적인 답입니다.
  • DKIM이 검증되지 않음. 게시된 키가 서명기가 쓰는 키와 다르거나 — DNS의 DKIM 키가 도메인에 추가한 그 키인지 확인하세요 — 전송 중이나 서명 후에 메시지가 변경된 경우입니다. 메일링 리스트 푸터나 링크를 재작성하는 게이트웨이는 모든 메시지에 이 일을 합니다. dkim=fail (body hash did not verify)는 변경 사례이고, 해석되지 않는 selector는 게시 사례입니다.
  • 둘 다 통과하는데 남의 도메인 기준. 정렬 문제입니다. 오래 가는 해법은 업체가 우리 도메인 아래 게시된 DKIM selector로 서명하게 하는 것입니다. 보통 업체가 주는 CNAME으로 처리하며, 이렇게 하면 Return-Path가 무엇이든 서명 도메인이 우리 From:과 정렬됩니다.

사례: 월요일부터 바운스가 시작된 청구서 발송 앱

재무팀의 청구서 발송 앱이 2년째 외부 서비스를 통해 릴레이하고 있었습니다. 월요일부터 Gmail 수신자에게 가는 청구서가 전부 5.7.26으로 튕기는데, 사내 Microsoft 365 사용자에게는 정상 도착합니다. 테스트 메일의 헤더는 업체 바운스 도메인 기준 spf=pass, dkim=neutral, dmarc=fail, header.from=example.com을 보여 줍니다. dig +short TXT _dmarc.example.com이 타이밍을 설명합니다. 보안팀이 주말 사이 정책을 p=none에서 p=reject로 올린 것입니다. 이 앱은 한 번도 정렬된 적이 없었고, 다만 그동안 집행 대상이 아니었을 뿐입니다. 해결은 업체의 DKIM CNAME을 example.com 아래 게시해 서명이 정렬되게 하는 것이고, 새 selector에 dig를 걸어 확인한 다음 실제로 한 통 보내 검증합니다. DNS가 퍼지는 동안에는 정책을 하루만 p=none으로 되돌리면 바운스가 즉시 멈춥니다.

실제 발송으로, 그다음 보고서로 확인하기

DNS 조회는 증명이 아닙니다 — 받는 쪽이 동의해야 합니다. 우리가 통제하는 Gmail 주소로 다시 보내 헤더가 dmarc=pass인지, 그리고 header.from과 일치하는 도메인에서 spf=pass나 dkim=pass 중 하나가 찍히는지 확인하세요. 나머지는 보고서가 해 줍니다. DMARC 레코드의 rua 주소는 어떤 메시지가 실패했는지 식별하는 일일 보고서를 받습니다. 요란하게 튕긴 발신자가 아니라 잊고 있던 발신자를 찾아내는 경로가 바로 이것입니다.

다시 겪지 않기: 먼저 보고받고, 나중에 집행하기

5.7.26 장애는 대개 자초한 것이고, 순서가 그것을 막아 줍니다. 보고만 요청하는 정책을 먼저 게시하고, 청구·티켓·CRM·모니터링·아무도 말해 주지 않은 마케팅 플랫폼까지 모든 정상 발신자가 정렬된 상태로 보고서에 나타날 때까지 모은 다음, 그때 quarantine과 reject로 조입니다. 어느 서비스가 어느 selector로 서명하는지 목록으로 남겨 두세요. 업체가 키를 교체하는 다음번에 찾게 될 문서입니다.

5.7.25·5.7.1, 그리고 스로틀링과 무엇이 다른가

5.7.25는 인증이 아니라 역방향 DNS입니다. 발신 IP에 PTR 레코드가 없거나, 정방향 DNS 항목이 그 발신 IP를 가리키지 않아 차단된 경우입니다. SPF를 고쳐도 이 오류에는 닿지 않습니다. 5.7.1은 정책 거부의 묶음입니다 — 보내는 쪽이나 받는 쪽 도메인이 해당 메일을 금지하는 정책을 갖고 있거나, From: 헤더가 없거나 유효하지 않거나, Message-ID가 없거나, 그 밖에 RFC 5322를 만족하지 못하는 경우입니다. 우리 DNS가 아니라 메시지나 수신자 규칙을 가리킵니다. 하나 더 기억해 둘 구분이 있습니다. 4.7.28 스로틀은 일시적이어서 정상적인 발신자는 재시도로 통과하지만, 여기 나온 5로 시작하는 코드는 모두 영구적이며 우리 쪽 변경을 요구합니다.

다음에 Gmail이 5.7.26으로 메일을 돌려보내면 이 순서를 거꾸로 따라가 보세요. 두 문장 중 실제로 어느 쪽을 받았는지, Authentication-Results 헤더가 spf·dkim·dmarc에 대해 무엇이라고 말하는지, TXT 레코드 세 개에 무엇이 들어 있는지, 그리고 그중 어느 것이 지금 추적 중인 발신자와 맞지 않는지입니다.

관련 질문

DMARC를 게시한 적이 없는데 왜 5.7.26이 나오나요?

두 가지를 확인해 보세요. 먼저 바운스에 실린 문장입니다. SPF나 DKIM으로 인증하라는 쪽은 모든 발신자에게 적용되는 Gmail의 기본 요구사항이고, DMARC 레코드와 무관하게 나타납니다. 다음은 하위 도메인에서 보내고 있는지입니다. 조직 도메인의 DMARC 레코드는 하위 도메인에도 적용되고 하위 도메인 정책을 따로 지정할 수도 있으므로, mail.example.com에 직접 게시하지 않은 레코드가 그 주소로 보낸 메일에 집행될 수 있습니다.

SPF는 통과하는데 왜 DMARC는 계속 실패하나요?

검사 대상 주소가 다르기 때문입니다. SPF는 Return-Path로 나타나는 봉투 발신자를 검증하지만, DMARC는 header From:의 도메인이 SPF 도메인이나 DKIM 도메인 중 하나와 정렬될 것을 요구합니다. Return-Path를 자기 바운스 도메인으로 바꾸는 릴레이라면 spf=pass인데 정렬된 것은 없는 상태가 만들어집니다. Authentication-Results 줄에서 smtp.mailfrom과 header.from을 비교해 보세요. 둘이 서로 다른 조직 도메인이고 DKIM이 우리 도메인으로 서명하지 않는다면, DMARC는 설계대로 실패합니다.

하루 5,000통 미만이면 DMARC가 필요 없나요?

모든 발신자에게 SPF 또는 DKIM은 필요합니다. 기본 요구사항이고, 이를 건너뛰면 인증되지 않은 발신자 바운스가 나옵니다. DMARC와 From: 헤더 정렬, 마케팅 메일의 원클릭 수신거부는 Gmail 계정으로 하루 5,000통을 넘게 보내는 발신자의 요구사항으로 명시되어 있습니다. 그 아래라도 DMARC를 게시해 둘 값어치는 있습니다. 우리 도메인을 사칭해 보내는 곳이 있는지 알아내는 수단이 집계 보고서이기 때문입니다.

직접 보내는 메일은 되는데 전달(forwarding)된 메일만 튕깁니다.

전달은 경로를 바꾸고, 때로는 메시지도 바꿉니다. SPF는 접속해 온 서버를 기준으로 평가되므로 전달 서버가 우리 메시지를 중계하는 순간 검사 대상은 그 서버의 IP가 되고 우리 SPF 레코드는 더 이상 이를 포함하지 않습니다. DKIM은 서명된 내용이 그대로인 한 전달을 견디며, 정렬된 DKIM 서명이 두 인증 방식 중 더 튼튼한 이유가 이것입니다. 전달 서버가 푸터를 붙이거나 링크를 재작성하면 body hash가 깨지면서 두 검사가 함께 무너집니다.

DNS를 고친 뒤 얼마나 지나야 메일이 나가나요?

바꾼 레코드의 TTL과 수신 측이 캐시한 내용에 달려 있어서, 인용할 만한 단일 숫자는 없습니다. 기다리는 대신 확인하세요. 사내 밖 장비나 공개 리졸버에서 dig를 걸어 새 값이 돌아올 때까지 본 다음, 실제 테스트 메일을 보내 Authentication-Results 헤더를 읽습니다. 받는 쪽이 실제로 무엇을 평가했는지 보고하는 것은 그 헤더뿐이므로, 확인으로 인정할 수 있는 근거도 그것 하나입니다.

참고 자료

Haneul Seo

Infrastructure engineer · 10+ years running Linux fleets

같은 카테고리 다른 글

AADSTS50011Fixed

Microsoft Entra ID: AADSTS50011, 요청에 지정된 redirect URI 가 앱에 등록된 redirect URI 와 일치하지 않음

로그인은 끝까지 성공했는데 마지막 한 단계에서 Entra ID 가 거부합니다. 앱이 보낸 redirect_uri 가 등록된 URI 중 어느 것과도 문자 단위로 같지 않기 때문입니다. 비교는 대소문자를 구분하고 끝의 슬래시를 세며, localhost 를 제외하면 https 를 요구하고 포트도 일치해야 합니다. 목록도 web·spa·publicClient 세 개로 나뉘어 있고, application 객체가 아닌 service principal 에 넣은 URI 는 동기화 과정에서 사라질 수 있습니다. 오류 메시지에서 URI 와 앱 ID 를 꺼내 az ad app show 로 대조하고, az ad app update 나 Graph PATCH 로 정확한 문자열을 넣은 뒤 3~5분 기다리면 됩니다.

Microsoft Entra ID
535 5.7.139Workaround

Exchange Online: 535 5.7.139 Authentication unsuccessful, SmtpClientAuthentication is disabled

smtp.office365.com 으로 메일을 보내던 스캐너·스크립트·앱이 535 5.7.139 로 멈추는 이유는 SMTP AUTH 프로토콜이 테넌트 전체, 해당 메일박스, 또는 Basic 인증을 막는 인증 정책·보안 기본값 중 어딘가에서 꺼져 있기 때문입니다. 문구(Tenant, Mailbox, 'did not meet the criteria')를 읽고 Get-TransportConfig·Get-CASMailbox·Get-AuthenticationPolicy 로 확인한 뒤, 테넌트 전체가 아니라 필요한 메일박스 하나만 엽니다. Basic SMTP AUTH 는 다리일 뿐입니다. Microsoft 는 2026년 12월 말 기존 테넌트에서 기본 비활성화하므로 발신자를 OAuth·High Volume Email·릴레이 커넥터로 옮겨야 합니다.

Exchange Online (Microsoft 365)
Error code: 5003Fixed

Zoom: "Unable to connect" 오류 코드 5003 — 브라우저는 되는데 데스크톱 앱만 Zoom 에 못 붙을 때

오류 5003 은 같은 PC 의 웹 클라이언트는 정상 입장하는데 Zoom 데스크톱 앱이 Zoom 서버와의 연결을 끝내지 못하는 상태입니다. 앱은 브라우저보다 더 많은 것을 필요로 합니다. Zoom 방화벽 문서는 미팅용 TCP 443/8801/8802 와 UDP 3478/3479/8801–8810, 인증서 검증용 CA 호스트 목록을 들고, zoom.us 와 *.zoom.us 를 프록시·SSL 검사에서 제외하라고 권고합니다. 포트 테스트, curl issuer 확인, 앱 내장 Network Connectivity Tool(Ctrl+Alt+Shift+D / Cmd+Option+Shift+D)로 어느 계층이 끊겼는지 보고 그 계층을 고치며, 재설치는 옆자리는 되는데 한 대만 실패할 때 씁니다.

Zoom
Slack cannot connect. / Last updated less than a minute ago…Fixed

Slack: 회사 프록시 뒤에서 뜨는 "Slack cannot connect"와 회색 "Last updated…" 띠

Slack은 채널을 평범한 HTTPS로 불러오지만 새 메시지는 443 포트로 Slack이 이름을 밝힌 wss-*.slack.com 호스트 셋(primary·backup·mobile)에 붙는 지속 WebSocket으로 받습니다. 프록시나 방화벽이 HTTP 쪽은 통과시키고 upgrade는 막으면 — 대개 wss 호스트에 SSL 복호화가 켜져 있거나 허용 목록이 slack.com에서 끝나기 때문에 — 브라우저는 멀쩡해 보이는데 앱은 회색 "Last updated…" 띠나 "Slack cannot connect."를 띄웁니다. 문제의 PC에서 curl 프로브 두 개로 어느 계층이 막혔는지 보고, wss 호스트 세 개를 복호화에서 예외 처리하고, my.slack.com/help/urls의 도메인을 전부 허용한 뒤 my.slack.com/help/test로 확인합니다.

Slack
locked for editingFixed

Word: 문서가 "locked for editing by another user"라며 열리지 않음

Word가 문서의 잠금(owner file)을 발견해 다른 누군가가 열어 두었다고 판단하고 읽기 전용 사본만 제안합니다. 대개는 아무도 열지 않았습니다: 크래시가 잠금을 남겼거나, 숨은 Word 프로세스가 여전히 파일을 쥐고 있는 것입니다. 어느 쪽인지 확인하고 Word 인스턴스를 모두 닫은 뒤 남겨진 ~$ owner file을 삭제하면 문서가 다시 편집 가능하게 열립니다.

Microsoft Word
sync error (red X)Fixed

OneDrive: 동기화 멈춤 — 일시 중지 또는 아이콘의 빨간 X

OneDrive 아이콘의 빨간 원 안 흰색 X나 일시 중지 상태는 동기화 루프가 멈췄다는 뜻입니다 — 파일은 로컬과 클라우드에 안전하지만 둘 사이를 오가지 않습니다. 활동 목록을 읽어 클라이언트 문제인지 특정 파일 문제인지 가른 뒤 OneDrive를 재시작하고, 그래도 안 되면 리셋하세요. 리셋은 동기화 연결을 다시 세울 뿐 파일을 삭제하지 않습니다.

OneDrive