🛡️ COMPAUTH Reason Codes

Microsoft 365 runs its own authentication check on top of SPF, DKIM and DMARC, and writes the answer into the Authentication-Results header as compauth=<result> reason=<nnn>. The three-digit code is the part worth reading. This page decodes all of them.

Published · Last verified · Maintained by TamingDNS

What Is Composite Authentication?

SPF, DKIM and DMARC each answer one narrow question, and plenty of legitimate mail fails at least one of them. Microsoft combines all three with signals of its own and publishes a single verdict about the From: domain. That verdict is compauth, and it is Microsoft's alone: no RFC defines it, and no other provider stamps it.

compauth=fail reason=001
compauth=: the verdict, one of pass, fail, softpass or none
reason=: the three-digit code saying why

The verdict on its own is nearly useless, because the failure codes do not mean the same thing as each other. One of them says the domain published an enforced policy and this message broke it. Another says the domain published nothing worth checking. Treating those as one finding is how a posture problem gets escalated as an attack, and how a real intra-organisation spoof gets filed as noise.

Does compauth=fail Mean the Message Was Blocked?

No. This is the most common misreading of the header, and Microsoft's own documentation is explicit about it:

Despite a compauth failure, the message might still be allowed if other assessments don't indicate a suspicious nature.

Our take: a reason code is a verdict on the authentication, not a record of what happened to the mail. A header cannot tell you whether a message was delivered, junked or quarantined, because it was written before that decision was made. Message trace in the Defender portal is where the delivery outcome lives.

What to do: read the code to learn what is wrong with the sender's authentication, then go to message trace to learn what became of the message. They are two separate questions and the header only answers the first.

Failure Codes

Four of these say something different about the same word. The gap between an explicit and an implicit failure is the gap between a domain that told receivers what to do and a domain that never said anything.

reason=000
Failed explicit authentication
The From domain publishes an enforced DMARC policy, and this message failed it. "Explicit" is the important word: the domain owner asked receivers to treat failures as failures, and Microsoft recorded that this was one. Of the failure codes, this is the one with a real policy behind it.
reason=001
Failed implicit authentication
Microsoft had nothing solid to authenticate against. The From domain either published no authentication records at all, or published ones that decline to assert anything: SPF ending ~all or ?all, or DMARC at p=none. So Microsoft fell back to its own implicit checks and those did not clear the message either.
reason=002
Blocked by an admin-configured spoof rule
This one is not a verdict about the sender's DNS at all. Somebody in your organisation configured a rule saying this specific sender/domain pair may not send spoofed mail, and this message hit that rule. The decision was made by an administrator, in your tenant, at some point in the past.
reason=010
Your own domain, failing your own enforced policy
A message arrived claiming to come from a domain your own organisation owns, it failed DMARC, and your policy says failures should be treated as failures. Staff being impersonated to staff, with your own published policy contradicting the claim.
reason=601
Your own domain, with nothing published to defend it
A message claimed to come from inside your organisation and could not authenticate. The 6xx family is Microsoft's second failure family, the implicit one, so unlike reason=010 there is no enforced DMARC policy standing behind the judgement.

Pass Codes Worth Recognising

A pass is not always a clean bill of health. Two of these pass a message whose DKIM signature is broken, and one passes on a guess about a domain that publishes no policy at all.

reason=100
Passed, with the domains aligned
The healthy code. An authentication check passed and the domain it passed for is the same domain the reader sees in the From line. Alignment is what DMARC exists to check, and reason=100 is what it looks like when it holds.
reason=108
Passed, but an earlier hop broke the DKIM signature
DKIM signs the body. Something rewrote the body after it was signed, so the signature no longer verifies. Microsoft attributed the change to a hop it considers legitimate rather than to an attacker. Composite authentication passed anyway.
reason=109
Would have passed DMARC, if the domain published it
The sending domain never published a DMARC record, so there was no policy to evaluate. Microsoft evaluated it anyway and the message would have passed. You will usually see dmarc=bestguesspass on the same line, which is Microsoft's way of saying the same thing about the DMARC check itself.
reason=115
Sent from a Microsoft 365 tenant, From domain is an accepted domain
The message originated inside a Microsoft 365 organisation, and the domain in the From address is one that organisation has configured as an accepted domain. Microsoft can see both ends of that, so it passes composite authentication on the strength of it.
reason=130
A trusted ARC sealer overrode the DMARC failure
DMARC failed, and an Authenticated Received Chain vouched for what the message looked like before an intermediary handled it. Microsoft accepted that testimony and passed the message. The usual cause is a mailing list or a forwarder that modified the message in transit and sealed a record of what it saw first.

Every Reason Code Microsoft Documents

Microsoft's complete table, in its own words. The bold rows are code families: a three-digit code Microsoft does not list individually still tells you something, because its first digit says which family it belongs to. The linked codes have a page of their own.

One trap in this table: the 3xx, 4xx and 9xx families are not passes. They mean composite authentication did not run, or ran and was bypassed. A message that was never checked is not a message that was cleared.

Code Verdict Microsoft's description
000 Fail The message failed explicit authentication (compauth=fail). The message received a DMARC fail and the DMARC policy action is p=quarantine or p=reject.
001 Fail The message failed implicit authentication (compauth=fail). The sending domain didn't have email authentication records published, or if they did, they had a weaker failure policy (SPF ~all or ?all, or a DMARC policy of p=none).
002 Fail The organization has a policy for the sender/domain pair that's explicitly prohibited from sending spoofed email. An admin manually configures this setting.
010 Fail The message failed DMARC, the DMARC policy action is p=reject or p=quarantine, and the sending domain is one of your organization's accepted domains (self-to-self or intra-org spoofing).
1xx Pass The message passed explicit or implicit authentication (compauth=pass).
100 Pass SPF passed or DKIM passed and the domains in the MAIL FROM and From addresses are aligned.
101 Pass The message was DKIM signed by the domain used in the From address.
102 Pass The MAIL FROM and From address domains were aligned, and SPF passed.
103 Pass The From address domain aligns with the DNS PTR record (reverse lookup) associated with the source IP address
104 Pass The DNS PTR record (reverse lookup) associated with the source IP address aligns with the From address domain.
108 Pass DKIM failed due to a message body modification attributed to previous legitimate hops. For example, the message body was modified in the organization's on-premises email environment.
109 Pass Although the sender's domain has no DMARC record, the message would pass, anyway.
111 Pass Despite a DMARC temporary error or permanent error, the SPF or DKIM domain aligns with the From address domain.
112 Pass A DNS timeout prevented the DMARC record from being retrieved.
115 Pass The message was sent from a Microsoft 365 organization where the From address domain is configured as an accepted domain.
116 Pass The MX record for the From address domain aligns with the PTR record (reverse lookup) of the connecting IP address.
130 Pass The ARC result from a trusted ARC sealer overrode the DMARC failure.
2xx Soft pass The message soft-passed implicit authentication (compauth=softpass).
201 Soft pass The PTR record for the From address domain aligns with the subnet of the PTR record for the connecting IP address.
202 Soft pass The From address domain aligns with the domain of the PTR record for the connecting IP address.
3xx Not evaluated The message wasn't checked for composite authentication (compauth=none).
4xx Not evaluated The message bypassed composite authentication (compauth=none).
501 Not evaluated DMARC wasn't enforced. The message is a valid non-delivery report (also known as an NDR or bounce message), and contact between the sender and recipient is previously established.
502 Not evaluated DMARC wasn't enforced. The message is a valid NDR for a message sent from this organization.
6xx Fail The message failed implicit email authentication (compauth=fail).
601 Fail The sending domain is an accepted domain in your organization (self-to-self or intra-org spoofing).
7xx Pass The message passed implicit authentication (compauth=pass).
701-704 Pass DMARC wasn't enforced because this organization has a history of receiving legitimate messages from the sending infrastructure.
9xx Not evaluated The message bypassed composite authentication (compauth=none).
905 Not evaluated DMARC wasn't enforced due to complex routing. For example, internet messages are routed through an on-premises Exchange environment or a non-Microsoft service before reaching Microsoft 365.

Descriptions verbatim from Anti-spam message headers in Microsoft 365 (page revised 12 August 2026).

🔧 Read a Real Header

Paste a full message header and the analyser decodes the compauth line alongside SPF, DKIM, DMARC, the ARC chain and the received path, then says what the combination amounts to.

Email Headers → DMARC Analyser → SPF Checker → DKIM Checker → Microsoft 365 Audit →