Microsoft Filtering Internals (EOP / Defender for Office 365)
Reading X-Forefront-Antispam-Report and X-Microsoft-Antispam headers, SCL and BCL scales with per-level actions, compauth reason codes, how EOP/MDO layers filter, and Tenant Allow/Block List mechanics from the sender's perspective.
How Microsoft 365 / Exchange Online Protection (EOP) filters inbound mail to business tenants, and how a sender or consultant reads the verdict from message headers. This is a different system from consumer Outlook.com filtering (SmartScreen-lineage, SNDS-visible) covered in Microsoft Sender Requirements — but the two share reputation inputs, and B2B senders live or die by EOP verdicts.
Diagnostic workflow: get a copy of the delivered (or junked/quarantined) message from a Microsoft 365 recipient, extract the full headers, and read three headers in order — Authentication-Results (did auth pass?), X-Forefront-Antispam-Report (what verdict and why), X-Microsoft-Antispam (BCL). Microsoft's own parser: Message Header Analyzer at https://mha.azurewebsites.net/.
How the layers stack
- Connection filtering at the service edge — IP-based. Most spam is caught here. Inputs: Microsoft's blocked-senders list (see Microsoft Escalation Channels), tenant IP Allow/Block lists, IP reputation. Tenant IP block entries drop mail at the edge.
- Anti-spam policies (content filtering) — classify each message as bulk, spam, high confidence spam, phishing, or high confidence phishing; stamp SCL and BCL. Three policy tiers exist: the default policy, admin-created custom policies, and the Standard/Strict preset security policies (progressively more aggressive defaults; preset settings override custom policy settings for included recipients).
- Anti-phishing / spoof intelligence / composite authentication — Microsoft's implicit-auth layer (
compauth) that judges the From domain even when no DMARC record exists. - Defender for Office 365 (MDO) add-ons — impersonation protection (user/domain/mailbox-intelligence), Safe Links, Safe Attachments. Only in tenants with MDO licenses; produces the
CATvalues marked MDO-only below.
Policy changes take up to 1 hour to apply. When multiple detections fire, policies apply in precedence order and the highest-priority verdict wins.
X-Forefront-Antispam-Report header
Semicolon-separated field:value pairs, e.g. ...CTRY:;LANG:hr;SCL:1;SRV:;IPV:NLI;SFV:NSPM;PTR:;SFTY:;.... Undocumented fields are internal diagnostics. Documented fields:
| Field | Meaning |
|---|---|
ARC |
ARC evaluation: AAR (recorded Authentication-Results), AMS (message signature), AS (header signature with cv= chain validation: none/pass/fail) |
CAT |
Threat category applied (see table below) |
CIP:[IP] |
Connecting IP address — usable in tenant IP Allow/Block lists |
CTRY |
Source country/region from connecting IP (may differ from originating IP) |
DIR |
Directionality: INB inbound, OUT outbound, INT internal |
H:[helostring] |
HELO/EHLO string of the connecting server |
IPV:CAL |
Spam filtering skipped — source IP was on the tenant IP Allow List |
IPV:NLI |
IP not found on any IP reputation list |
LANG |
Message language country code (e.g. ru_RU) |
PTR:[ReverseDNS] |
PTR (reverse DNS) of the source IP |
SCL |
Spam confidence level (scale below) |
SFTY |
Phishing safety-tip marker: 9.19 domain impersonation, 9.20 user impersonation, 9.25 first-contact safety tip |
SFV |
Spam filtering verdict (table below) |
SRV:BULK |
Identified as bulk by BCL threshold; with MarkAsSpamBulkMail on (default), bulk mail is marked spam at SCL 6 |
X-CustomSpam:[ASFOption] |
Matched an Advanced Spam Filter (ASF) setting (content heuristics like embed tags, JavaScript in HTML, empty message). Added after mail flow rules run, so rules can't act on it |
CAT (category) values
| Value | Meaning | Value | Meaning |
|---|---|---|---|
AMP |
Anti-malware | INTOS |
Intra-org phishing |
BIMP |
Brand impersonation (MDO) | MALW |
Malware |
BULK |
Bulk | OSPM |
Outbound spam |
DIMP |
Domain impersonation (MDO) | PHSH |
Phishing |
FTBP |
Anti-malware common-attachments filter | SAP |
Safe Attachments (MDO) |
GIMP |
Mailbox-intelligence impersonation (MDO) | SPM |
Spam |
HPHSH/HPHISH |
High confidence phishing | SPOOF |
Spoofing |
HSPM |
High confidence spam | UIMP |
User impersonation (MDO) |
SFV (spam filtering verdict) values
| Value | Meaning |
|---|---|
SFV:NSPM |
Marked nonspam; delivered normally |
SFV:SPM |
Marked spam by content filtering |
SFV:BLK |
Blocked — sender is on the recipient user's Blocked Senders list (filtering skipped) |
SFV:SFE |
Allowed — sender is on the recipient user's Safe Senders list (filtering skipped) |
SFV:SKA |
Skipped filtering — sender/domain on the anti-spam policy allowed list; delivered to Inbox |
SFV:SKB |
Marked spam — sender/domain on the anti-spam policy blocked list |
SFV:SKN |
Marked nonspam before filtering (e.g. mail flow rule set SCL -1 / bypass) |
SFV:SKS |
Marked spam before filtering (e.g. mail flow rule set SCL 5–9) |
SFV:SKQ |
Released from quarantine to intended recipients |
Consultant reading: SKA/SFE/SKN mean the recipient side whitelisted you (fragile — placement depends on an override, not reputation). SKB/BLK mean the recipient side blocked you explicitly — no amount of sender-side reputation work fixes that; the recipient org must remove the entry.
SCL — Spam Confidence Level
Stamped as an X-header on every inbound message. Values 2, 3, 4 are never stamped by filtering. SCL 7 is typically set not by spam filtering itself but by analyst grading, DMARC failures, or mail flow rules.
| SCL | Definition | Default action |
|---|---|---|
| -1 | Skipped filtering (safe sender/recipient, or IP Allow List) | Inbox |
| 0, 1 | Not spam | Inbox |
| 5, 6 | Spam | Default/custom policies & Standard preset: Junk folder · Strict preset: quarantine |
| 7, 8, 9 | High confidence spam | Default/custom policies: Junk folder · Standard & Strict presets: quarantine |
BCL — Bulk Complaint Level
Stamped in the X-Microsoft-Antispam header (e.g. X-Microsoft-Antispam: BCL:5;). Assigned to mail from recognized bulk senders ("gray mail"), from Microsoft-internal and external sources, based on complaint behavior. This is the header that matters most to ESPs: it is effectively Microsoft's published per-sender complaint-reputation score.
| BCL | Meaning |
|---|---|
| 0 | Not from a bulk sender |
| 1–3 | Bulk sender generating few complaints |
| 4–7 | Bulk sender generating a mixed number of complaints |
| 8–9 | Bulk sender generating a high number of complaints |
Threshold and action (message is treated as Bulk when BCL meets or exceeds the threshold):
| Policy | BCL threshold | Action at/above threshold |
|---|---|---|
| Default and new custom anti-spam policies | 7 | Junk Email folder |
| Standard preset security policy | 6 | Junk Email folder |
| Strict preset security policy | 5 | Quarantine |
Practical implication for a sender: BCL ≤ 3 inboxes everywhere; BCL 4 is junked by Strict-preset tenants (recommended opt-in minimum 5 in the Promotions-folder feature); BCL 5–6 is junked/quarantined by preset-policy tenants; BCL ≥ 7 is junked by default in every tenant. Recipient admins can tune the threshold and can see per-sender bulk volume via the "bulk senders insight" in the Defender portal.
Promotions folder (preview, 2026): tenants can opt to deliver bulk mail below the BCL threshold (even BCL 0 bulk) to a Promotions folder instead of the Inbox, via a mail flow rule stamping X-MS-Exchange-Organization-BulkStamping: 1 plus the "Bulk moves enabled" anti-spam policy setting. Microsoft 365 learns from users moving messages in/out of the folder. Mail still reaches the Inbox if the sender is in the user's Safe Senders list. Sender takeaway: even complaint-clean bulk mail may stop landing in Microsoft 365 Inboxes by classification, mirroring Gmail's tabs.
Authentication-Results and composite authentication
Microsoft stamps standard spf=, dkim=, dmarc= results (see Authentication-Results Header) plus Microsoft-specific fields:
dmarc=values include the nonstandardbestguesspass— no DMARC record exists, but the message would have passed if one did.action=on DMARC:oreject(rejected per policy),pct.quarantine/pct.reject(failed DMARC but delivered becausepct< 100 randomly exempted it),permerror,temperror.compauth— composite authentication: Microsoft's blended verdict combining SPF, DKIM, DMARC, and message signals, evaluated against the From (5322.From) domain. Acompauth=faildoesn't guarantee junking if other signals are clean.reason— three-digit code explaining the compauth result:
| Code | Meaning |
|---|---|
| 000 | Failed explicit auth: DMARC fail with p=quarantine/p=reject |
| 001 | Failed implicit auth: no auth records, or weak ones (SPF ~all/?all, DMARC p=none) |
| 002 | Org policy explicitly prohibits this sender/domain pair from spoofing |
| 010 | DMARC fail with reject/quarantine and the sending domain is one of the org's own accepted domains (intra-org spoof) |
| 1xx (100–130) | Passed: 100 SPF or DKIM passed with alignment · 101 DKIM by From domain · 102 MAIL FROM/From aligned + SPF pass · 103/104 PTR aligns with From domain · 108 DKIM fail attributed to legitimate prior hop · 109 no DMARC record but would pass · 111 DMARC temp/permerror but SPF/DKIM aligned · 112 DNS timeout on DMARC lookup · 115 sent from an M365 org where From is an accepted domain · 116 From-domain MX aligns with connecting IP's PTR · 130 trusted ARC sealer overrode DMARC failure |
| 2xx (201, 202) | Soft-pass on PTR/subnet alignment (compauth=softpass) |
| 3xx / 4xx / 9xx | Not checked / bypassed (compauth=none) |
| 501, 502 | DMARC not enforced: valid NDR with established contact / valid NDR for own org's mail |
| 6xx (601) | Failed implicit auth; 601 = intra-org spoof of an accepted domain |
| 7xx (701–704) | DMARC not enforced — org has a history of legitimate mail from this infrastructure |
| 905 | DMARC not enforced due to complex routing (on-prem or third-party hop before M365) |
Reason 001 is the code ESP consultants see most: it means the sender had no or weak authentication, and Microsoft junked on implicit-auth suspicion. Fix: aligned SPF+DKIM and a DMARC record — the same remediation as the Outlook.com May 2025 mandate.
Tenant Allow/Block List (TABL) — what recipient tenants control
Per-tenant override list at https://security.microsoft.com/tenantAllowBlockList, applied during mail flow and at time-of-click. Entry types: domains & email addresses (matched on the From/5322.From address, not MAIL FROM), spoofed senders, URLs, files, IP addresses, Teams domains. Block entries take precedence over allow entries. Entries take effect within ~5 minutes.
Block behavior:
| Blocked entity | Effect |
|---|---|
| Domain/email address | Message treated as high confidence phishing and quarantined (not merely spam); the tenant's own users also can't send to it (550 5.7.703 ... blocked by your organization using Tenant Allow Block List) |
| URL or file | Message quarantined as high confidence phishing / malware respectively |
| IP address | Dropped at the service edge |
| Spoofed sender | Manual override of a spoof-intelligence allow |
Block-entry expiry: domains/addresses, files, URLs default 30 days (configurable to 90 or never); spoofed senders, IPs, and Teams entries never expire.
Allow-entry mechanics (why "just get them to whitelist us" is constrained):
- Admins cannot directly create allow entries for malware or high-confidence-phishing verdicts — those require submitting the message/URL/file to Microsoft via the Submissions page (
https://security.microsoft.com/reportsubmission) and confirming it clean; only then can an allow entry be created. Messages identified as malware or high confidence phishing are always filtered regardless of allow entries. - Direct allow entries for domains/addresses and URLs can override only: bulk, spam, high confidence spam, and (non-high-confidence) phishing.
- Allow entries for domains/addresses, files, and URLs are kept for 45 days after the filtering system last judges the entity clean, then auto-removed (or admin-set to expire ≤30 days after creation). Spoofed-sender allows never expire. Microsoft may auto-remove allow entries it deems unnecessary (with an alert).
- An allowed sender is still subject to the rest of the stack: the message must also pass auth, URL, and file checks — an allow skips only the filters tied to the allowed entity.
- URL allows created via submission cover variations/sub-paths of the reported URL automatically.
Sender-side consequence: if your mail is verdicting as high-confidence phishing at a customer's tenant (commonly caused by a blocked URL/domain in their TABL, or spoof/impersonation detection), the recipient admin can't simply allowlist you — the path runs through admin submission to Microsoft. Get the recipient admin to submit the message as a false positive; Microsoft's review may create the allow.
FAQ material relevant to external senders
From Microsoft's anti-spam FAQ, the documented causes when legitimate mail is junked at Microsoft 365, and fixes:
| Cause | Fix |
|---|---|
| Auth failure (SPF/DKIM/DMARC → compauth fail) | Correct SPF, DKIM, DMARC for the sending domain |
| Sender reputation (IP/domain history, blocklists, low volume) | Check third-party blocklists, valid PTR, review SNDS |
| Content triggers (excessive links, URL shorteners, form tags, embedded scripts, image-only) | Review content; recipient may have ASF options enabled |
| BCL met tenant threshold | Not spam — a bulk classification; lower complaints or recipient tunes threshold/safe-senders |
| Recipient overrides (mail flow rule, policy block list, user Blocked Senders) | Only the recipient can remove |
| Intermediate filtering service hides true source IP | Recipient enables Enhanced Filtering for Connectors ("skip listing") |
Microsoft's outbound best practices for reaching Microsoft 365 (their own list): sending domain resolves in DNS (no A/MX record → mail is routed through Microsoft's high-risk pool regardless of content); PTR record on the source IP; HELO/EHLO and MAIL FROM consistent, domain-based, HELO matching the PTR; correct SPF; DKIM signed with relaxed canonicalization (strict header canonicalization can break when transiting the service); accurate WHOIS; RFC 3464-format bounces; remove addresses that NDR as nonexistent; monitor SNDS.
Outbound throttling inside the service (relevant when a compromised customer sends through Microsoft): a user sending >50% spam within a time window is blocked from sending; outbound spam is routed through the high-risk delivery pool (separate IPs) to protect the normal pool.
Related
- Microsoft Sender Requirements — consumer Outlook.com policies, error codes, 2025 auth mandate
- Microsoft Escalation Channels — delist portal, sender support, remediation map
- Microsoft SNDS & JMRP — reputation data and feedback loop
- Authentication-Results Header — the RFC 8601 baseline Microsoft extends
Sources
- https://learn.microsoft.com/en-us/defender-office-365/message-headers-eop-mdo
- https://learn.microsoft.com/en-us/defender-office-365/anti-spam-bulk-complaint-level-bcl-about
- https://learn.microsoft.com/en-us/defender-office-365/anti-spam-spam-confidence-level-scl-about
- https://learn.microsoft.com/en-us/defender-office-365/anti-spam-protection-faq
- https://learn.microsoft.com/en-us/defender-office-365/tenant-allow-block-list-about