# Someone is sending email from your domain: how to stop it with DMARC

> Confirm whether your domain is being spoofed or your account is compromised, read the evidence in headers and DMARC reports, then lock the domain down with SPF, DKIM and DMARC p=reject.

Source: https://www.epifive.com/blog/someone-sending-emails-from-my-domain-stop-spoofing-dmarc · Published 2026-11-12 · EpiFive

## Key takeaways

- A spoofed message fails DMARC because neither SPF nor DKIM aligns with the From domain; a message that passes with your domain did not come from a stranger.
- You can't prevent forgery itself, only make receivers that honor DMARC reject it, so p=reject is the end goal.
- Start at p=none with a rua address, read the aggregate reports, and fix every legitimate sender before tightening the policy.
- Domains and subdomains that never send mail should publish v=spf1 -all and a DMARC p=reject record immediately.
- DMARC inherits to subdomains, but SPF and DKIM do not, so each sending subdomain needs its own records.

If someone is sending email that appears to come from your domain, the fix is to publish SPF, turn on DKIM signing for your own domain, and move your DMARC policy to `p=reject` so receivers that enforce DMARC refuse the forged mail. Before you change anything, confirm that the mail really is forged: read the `Authentication-Results` header of a sample message. If it fails DMARC, it is spoofing; if it passes with your domain, it left your own systems and you have a different problem.

## Who this is for and what you will have at the end

This guide is for owners and administrators of a small or mid-sized business who have received a report that fake invoices, payment requests or phishing messages are going out in the company's name. It assumes you manage DNS for the domain and, ideally, use Microsoft 365, although the DNS records apply to any mail provider.

At the end you will have:

- A way to tell forged mail from mail sent by your own accounts and apps.
- DMARC reports arriving in a mailbox you control, and a method for reading them.
- SPF, DKIM and DMARC records that tell receivers to reject mail that fails.
- Locked-down records for parked domains and subdomains that never send mail.
- A short list of what to do while you wait for the policy to take effect.

## Why anyone can send mail as your domain

SMTP, the protocol behind internet email, doesn't validate that a sender is who they claim to be. A message carries two sender values. The MAIL FROM address (also called `5321.MailFrom`, the envelope sender or Return-Path) is used between mail servers and for bounces. The From address (`5322.From`) is what the recipient sees in their mail app. They can be in different domains, and an attacker controls both.

Microsoft's documentation gives the classic example: the envelope sender is `dubious@proseware.com` while the visible From address is `security@woodgrovebank.com`. The transmission is valid SMTP, yet it deceives the recipient. SPF checks only the MAIL FROM domain, and DKIM checks only the domain that signed the message, so an attacker can pass both with a domain they own while showing yours in the From line. DMARC closes that gap by requiring that the domain SPF or DKIM validated **aligns** with the From domain, and by telling receivers what to do when it doesn't.

This means two things for you. You can't stop someone typing your address into a From field. You can make every receiver that honors DMARC reject the message, and you can see how much of it is happening.

## Step 1: Confirm it is spoofing and not a compromised account

Ask the person who received the message to send it to you as an attachment, or to copy the full headers. Outlook's menu paths for viewing headers are on Microsoft's support page, "View internet message headers in Outlook", linked in the references. Paste the headers into Microsoft's Message Header Analyzer if you want them parsed.

Find the `Authentication-Results` header. The three fields that matter are `smtp.mailfrom=` (the envelope domain SPF checked), `header.d=` (the domain that signed the message with DKIM) and `header.from=` (the visible From domain).

Microsoft's DMARC troubleshooting page shows this header, from a message where SPF and DKIM pass individually but neither aligns with the From address:

```text
Authentication-Results: spf=pass (sender IP is 198.51.100.10)
  smtp.mailfrom=bounces.adatum.com; dkim=pass (signature was verified)
  header.d=adatum.com; dmarc=fail action=oreject
  header.from=contoso.com;compauth=fail reason=000
```

That is documented output from learn.microsoft.com, not output from your tenant. Read it like this: `header.from=contoso.com` is the forged domain, while `smtp.mailfrom` and `header.d` belong to a different domain, so `dmarc=fail`.

Use the result to decide what you are dealing with:

| What the header shows | Most likely cause | Next step |
|---|---|---|
| `dmarc=fail`, `smtp.mailfrom` and `header.d` in someone else's domain | Spoofing from outside | Continue with steps 2 to 6 |
| SPF or DKIM passes and the domain is yours (for example `header.d=contoso.com`, `dmarc=pass`) | Mail left a system you authorize: a compromised mailbox, a stolen app credential or a forgotten sender | Treat as an account incident: reset passwords, enforce MFA, review the sending system |
| `dmarc=bestguesspass` or `dmarc=none` | You have no DMARC record at all | Publish one in step 3 |
| `spf=fail` with `-all`, but the message was still delivered | The receiver doesn't enforce, or DMARC isn't set | Publish DMARC; enforcement depends on the receiver |

The second row is an inference from how alignment works rather than a rule Microsoft states in one sentence: a message aligned with your domain by SPF or DKIM can only have been sent by a source that SPF authorizes or that holds your DKIM key. If that describes your spam, tighten account security first. The [small business MFA rollout checklist](https://www.epifive.com/blog/small-business-mfa-rollout-staff-checklist) covers that side.

## Step 2: Check what your domain publishes today

Before you change records, look at what exists. In PowerShell, `Resolve-DnsName` (also used in Microsoft's own troubleshooting page) shows the DMARC record:

```powershell
Resolve-DnsName -Name "_dmarc.contoso.com" -Type TXT | Select-Object -ExpandProperty Strings
```

Check the SPF record the same way, against the domain itself:

```powershell
Resolve-DnsName -Name "contoso.com" -Type TXT | Select-Object -ExpandProperty Strings
```

You are looking for three things. A single record starting `v=spf1`, because two SPF records cause `permerror`. A `_dmarc` TXT record starting `v=DMARC1;`, and its `p=` value. And whether the SPF record ends in `-all`. If no `_dmarc` record exists, Microsoft 365 reports `dmarc=bestguesspass` or `dmarc=none` for your mail when it receives it, and nobody is told to reject forgeries.

If you use Microsoft 365, you can also check DKIM:

```powershell
Get-DkimSigningConfig | Format-List Domain, Enabled, Selector1CNAME, Selector2CNAME
```

`Enabled` should be `True` for your custom domain. The full procedure for publishing the CNAME records and enabling signing is in [SPF, DKIM and DMARC for Microsoft 365](https://www.epifive.com/blog/spf-dkim-dmarc-microsoft-365-setup), so this article doesn't repeat it.

## Step 3: Publish DMARC at p=none with reporting

Don't jump to `p=reject` yet. If a legitimate sender such as a billing tool or newsletter service isn't aligned, `p=reject` makes receivers refuse your real mail. Start with monitoring, which also gives you evidence of how much forged mail exists.

First create a place for reports. Microsoft recommends a dedicated mailbox or a Microsoft 365 Group, not a person's inbox, and says to start with `rua` only because forensic (`ruf`) reports can be high volume. Then add one TXT record at your DNS host:

```text
Hostname: _dmarc
Type: TXT
Value: v=DMARC1; p=none; pct=100; rua=mailto:dmarc-reports@contoso.com
```

Microsoft's rollout example uses the same structure, with `rua` and `ruf` addresses. A few details from the documentation:

- The hostname `_dmarc` is required, and there must be only one `_dmarc` TXT record.
- `p=none` takes no action on failing mail but still produces reports.
- `pct` defaults to 100 if you leave it out.
- Aggregate reports are typically sent once a day and describe the previous day.
- If the report address is in a different domain from the one you're monitoring, that other domain must publish a TXT record named `contoso.com._report._dmarc` with the value `v=DMARC1;`. Without it receivers don't deliver the reports.
- Microsoft 365 doesn't send forensic reports even if your record has a `ruf` address, so other providers' reports are the only source.

The reports are XML, often compressed. You can read them by hand while the volume is small, or use a DMARC reporting service listed in the Microsoft Intelligent Security Association catalog.

## Step 4: Read the aggregate reports

Give the record at least a few days so that receivers send their summaries. Then look at each `<record>` in the XML. Microsoft's page explains the fields that matter:

| Element | What it tells you |
|---|---|
| `<source_ip>` | The server that sent mail using your domain |
| `<count>` | How many messages came from that IP |
| `<disposition>` | What the receiver did: `none`, `quarantine` or `reject` |
| `<dkim>` and `<spf>` under `<policy_evaluated>` | Whether DKIM or SPF **aligned** with your From domain |
| `<domain>` under `<auth_results>` | The domain SPF or DKIM actually validated |

Sort the sources into three groups:

1. **Known and aligned.** Your Microsoft 365 tenant, with SPF aligned. Healthy; no action.
2. **Known but not aligned.** A legitimate service where authentication passes but alignment fails. The page's example: SPF `pass` in `auth_results` but `fail` in `policy_evaluated`. The service uses its own domain in MAIL FROM or signs with its own domain. Fix it at the service: have it sign DKIM with your domain, or change its MAIL FROM to your domain or a subdomain.
3. **Unknown, high volume, everything failing.** Microsoft's table describes this pattern as a potential spoofing or phishing campaign and says no action is needed because your DMARC policy protects recipients once it is enforced. This is the group you are trying to stop.

Don't skip group 2. Every legitimate sender you leave unaligned becomes a bounce the day you reach `p=reject`. Common examples named in Microsoft's table are services that use their own MAIL FROM, forwarded mail and mailing lists. Forwarding is the exception: it breaks SPF and can break DKIM when the body changes, so a share of failures from forwarders is normal.

## Step 5: Fix SPF and DKIM for the legitimate senders

For each legitimate sender from group 2, use the vendor's documentation to find its `include:` value or its DKIM setup. For Microsoft 365 as the only sender, Microsoft's documented SPF record is:

```text
v=spf1 include:spf.protection.outlook.com -all
```

For a domain with an on-premises server and a bulk mailer on a subdomain, the same page gives:

```text
contoso.com            TXT  v=spf1 ip4:192.168.0.10 include:spf.protection.outlook.com -all
marketing.contoso.com  TXT  v=spf1 include:servers.adatum.com include:spf.protection.outlook.com -all
```

Keep these rules in mind:

- One SPF record per domain or subdomain.
- Fewer than 10 DNS lookups. `include`, `a`, `mx`, `exists` and `redirect` each count, and so do nested includes; `ip4`, `ip6` and `all` don't. If you exceed the limit, see [fixing an SPF record that is too long](https://www.epifive.com/blog/spf-record-too-long-10-lookup-limit).
- Use `-all`. Microsoft notes that DMARC treats `-all` and `~all` both as SPF failures, but a `~all` failure is effectively ignored by DMARC when the message has no DKIM signature.
- Put services you don't control, such as bulk mail platforms, on a subdomain. Each subdomain needs its own SPF record and DKIM setup, because unlike DMARC they don't inherit from the parent.

After each change, watch the next day's reports and confirm that the sender moved from group 2 to group 1.

## Step 6: Move to quarantine, then reject

Once the legitimate senders are aligned and the only failing traffic is unknown sources, tighten the policy in stages. Microsoft's recommended order is `p=none`, then `p=quarantine`, then `p=reject`, starting with a subdomain that has low mail volume and saving the parent domain for last. You can step `pct` through 10, 25, 50, 75 and 100 to limit the share of failing mail that gets the policy at first.

```text
Hostname: _dmarc
Type: TXT
Value: v=DMARC1; p=quarantine; pct=25; rua=mailto:dmarc-reports@contoso.com
```

When the reports stay clean at 100, finish with:

```text
Hostname: _dmarc
Type: TXT
Value: v=DMARC1; p=reject; pct=100; rua=mailto:dmarc-reports@contoso.com
```

What "reject" means depends on the receiver. Microsoft's page says the messages are typically discarded, and that a Microsoft 365 recipient with **Honor DMARC record policy** turned on rejects a failing message during SMTP with `550 5.7.1` and stamps `dmarc=fail action=oreject`. With `p=quarantine`, the message goes to Junk Email by default. Other providers make their own decisions, which is why DMARC lowers the volume of spoofing instead of removing it.

One side effect to know about: outbound mail from a Microsoft 365 domain that fails DMARC at the destination is routed through the high-risk delivery pool if your policy is `p=quarantine` or `p=reject`, and there is no override. Align your senders first, so that doesn't catch legitimate mail.

## Step 7: Lock down domains and subdomains that don't send mail

Attackers don't need your main domain. Old domains, typo-protection domains and unused subdomains are all usable for forgeries if nothing is published. For a registered domain that sends no mail, Microsoft documents two records:

```text
Hostname: @ (contoso.net)
Type: TXT
Value: v=spf1 -all

Hostname: _dmarc (contoso.net)
Type: TXT
Value: v=DMARC1; p=reject;
```

The `pct`, `rua` and `ruf` values are arguably unnecessary here because no valid mail should come from the domain. Microsoft's note also applies to your `*.onmicrosoft.com` domain: if you don't use it for email, add a DMARC record for it, which you do in the Microsoft 365 admin center under **Settings** > **Domains**, then the **DNS records** tab and **Add record**, with the TXT name `_dmarc` and the value `v=DMARC1; p=reject`. DMARC on your main domain also covers subdomains that have no record of their own, including ones that don't exist, unless a subdomain publishes its own `_dmarc` record.

## Troubleshooting

| Symptom | Likely cause | Fix |
|---|---|---|
| `dmarc=fail` but SPF and DKIM both pass | Neither domain aligns with the From address | Make the service sign with your domain or use your domain in MAIL FROM |
| `dmarc=temperror` or `dmarc=permerror` | DNS timeout, or a DMARC record with a syntax error | Check syntax with `Resolve-DnsName`, and keep exactly one `_dmarc` TXT record |
| No reports arrive | Wrong `rua` address, or external report address without the `_report._dmarc` record | Fix the address or publish `contoso.com._report._dmarc` in the receiving domain |
| Legitimate mail from a vendor is rejected after `p=reject` | The vendor isn't aligned | Add its DKIM signing with your domain; move it to a subdomain |
| Forwarded messages fail | Forwarding breaks SPF; body changes can break DKIM | Expect some failures; the receiving side can use trusted ARC sealers |
| You still see forged mail in some inboxes | The receiving provider doesn't enforce DMARC, or you're still at `p=none` | Confirm the published policy; enforcement is the receiver's decision |

If the spoofed mail targets your own users, a Microsoft 365 tenant can also deal with inbound forgeries of your domain. The [Tenant Allow/Block List guide](https://www.epifive.com/blog/tenant-allow-block-list-spoofed-senders) explains the spoofed sender entries, and Microsoft documents the anti-phishing setting **Honor DMARC record policy when the message is detected as spoof**.

## What to do while you wait

DNS changes and receivers' enforcement take time, and DMARC doesn't recall mail that was already sent. In the meantime:

- Tell customers and staff that you will never change bank details by email, and agree how payment changes are verified, for example by calling a known number.
- Report the phishing to the people it targeted, so they can block it on their side.
- Keep the sample headers and message copies so you can show which domain and IP the mail came from.

## Checklist

- Read the `Authentication-Results` header of a sample message and decide spoofing or compromised account.
- Check that exactly one SPF record and a `_dmarc` record exist.
- Publish `v=DMARC1; p=none; rua=...` and confirm reports arrive.
- Sort the aggregate report sources and align every legitimate sender.
- Move to `p=quarantine`, then `p=reject`, using `pct` steps, subdomains first.
- Publish `v=spf1 -all` and `p=reject` for parked domains.
- Review reports weekly at first and monthly once stable.

## What we checked

- Opened "Set up DMARC to validate email in Microsoft 365" on learn.microsoft.com on 2026-11-12 (page dated 2026-07-03): the record syntax, `p=none`/`quarantine`/`reject` rollout order, the `pct` steps 10, 25, 50, 75 and 100, and the parked-domain record `v=DMARC1; p=reject;`.
- Opened the SPF configuration page on 2026-11-12 and confirmed the Microsoft 365 record `v=spf1 include:spf.protection.outlook.com -all`, the parked-domain record `v=spf1 -all`, and the 10-lookup rules.
- Cross-checked the `Authentication-Results` fields (`smtp.mailfrom`, `header.d`, `header.from`, `dmarc`, `action`) between the DMARC page and the "Anti-spam message headers" page; both describe `dmarc=fail action=oreject` the same way.
- Documented output: the sample `Authentication-Results` header in step 1 is quoted from Microsoft's DMARC troubleshooting section, with `compauth=fail reason=000`. The reason code table on the headers page defines 000 as a DMARC fail where the sender's policy is `p=quarantine` or `p=reject`.
- Confirmed on the DMARC page that Microsoft 365 doesn't send forensic reports and that cross-domain report addresses need a `_report._dmarc` TXT record.
- Not checked hands-on: we did not run any command or change DNS on a live tenant or domain, and the second row of the step 1 table is our own reading of how alignment works. Steps follow Microsoft's documentation as of 2026-11-12.

Last tested: 2026-11-12

## References

- Set up DMARC to validate email in Microsoft 365: https://learn.microsoft.com/en-us/defender-office-365/email-authentication-dmarc-configure
- Set up SPF to identify valid email sources: https://learn.microsoft.com/en-us/defender-office-365/email-authentication-spf-configure
- How email authentication works in Microsoft 365: https://learn.microsoft.com/en-us/defender-office-365/email-authentication-about
- Anti-spam message headers (Authentication-Results and compauth reason codes): https://learn.microsoft.com/en-us/defender-office-365/message-headers-eop-mdo
- View internet message headers in Outlook: https://support.microsoft.com/office/cd039382-dc6e-4264-ac74-c048563d212c

## Frequently asked questions

### Can I stop someone from sending email that appears to come from my domain?

You can't stop a stranger from typing your address in the From field, because SMTP doesn't check it. You can make receivers reject those messages by publishing SPF, DKIM signing and a DMARC record with p=reject. Receivers that honor DMARC then reject or junk mail that fails authentication and alignment.

### How do I tell spoofing from a hacked mailbox?

Open the full message headers and read the Authentication-Results header. A spoofed message normally fails DMARC because neither SPF nor DKIM aligns with your From domain. A message that really left your tenant passes SPF or DKIM with your domain, so it points to a compromised account, a misconfigured app or an authorized sender that needs review.

### Will DMARC p=reject block my own legitimate email?

It can, if a legitimate sender such as a newsletter tool, scanner or billing system doesn't pass SPF or DKIM with your domain. That is why Microsoft recommends starting at p=none, reading aggregate reports, then moving to p=quarantine and p=reject in steps, using pct to limit the share of failing mail at first.

### Why am I not getting DMARC reports?

Check that the rua address is spelled correctly and the mailbox exists. If the report address is in a different domain, that domain must publish a TXT record at contoso.com._report._dmarc with the value v=DMARC1; or receivers won't deliver reports. Reports are typically sent once a day, and not every receiver sends them.

