---
title: "Check your DMARC record"
description: "Look up a domain's DMARC record at _dmarc, see the policy receivers apply, check the report addresses, and get the fix for each problem found."
url: https://www.unitpost.com/tools/dmarc-checker
section: Free tools
updated: 2026-11-02
---
# Check your DMARC record

DMARC is a TXT record at _dmarc.yourdomain that tells receivers what to do with mail whose From domain isn't backed by a passing, aligned SPF or DKIM result: deliver it anyway (p=none), send it to spam (quarantine) or refuse it (reject). It also says where to send reports. This checker reads the record, falls back to the parent domain when a subdomain has none, and checks the policy, syntax and report authorization.

> Interactive tool: https://www.unitpost.com/tools/dmarc-checker. The lookups go from your browser to a public DNS-over-HTTPS resolver. Nothing is sent to Unitpost, and there's no sign-up.

## DMARC tags

> 

A DMARC record is a list of `tag=value` pairs separated by semicolons, starting with `v=DMARC1`. A working record needs only `v`, `p` and, to see anything, `rua`; the other tags have defaults.

| Tag | Values | Default | What it does |
| --- | --- | --- | --- |
| `v` | `DMARC1` | Required | The version. Must come first, written exactly `DMARC1`. |
| `p` | `none`, `quarantine`, `reject` | Required in RFC 7489 | The policy for mail that fails DMARC on this domain. |
| `sp` | `none`, `quarantine`, `reject` | Same as `p` | The policy for subdomains. |
| `np` | `none`, `quarantine`, `reject` | Same as `sp`, else `p` | The policy for subdomains that don't exist (RFC 9989). |
| `pct` | 0 to 100 | 100 | The share of failing mail the policy applies to. Removed in RFC 9989. |
| `rua` | `mailto:` addresses | None | Where receivers send aggregate reports, usually daily XML files. |
| `ruf` | `mailto:` addresses | None | Where receivers send failure reports on single messages. Many large receivers don't send them. |
| `adkim` | `r`, `s` | `r` | DKIM alignment. Relaxed accepts a signing domain with the same organizational domain as From; strict needs an exact match. |
| `aspf` | `r`, `s` | `r` | SPF alignment: the same choice, for the Return-Path domain. |
| `fo` | `0`, `1`, `d`, `s` | `0` | When to send failure reports: `0` when SPF and DKIM both fail, `1` when either fails, `d` on a DKIM failure, `s` on an SPF failure. |

RFC 9989 replaced RFC 7489 in 2026. It removes `pct`, `rf` and `ri`, adds `t=y` as a testing switch (the policy applies one step softer) and adds `np` and `psd`. This checker reads records by RFC 7489's rules, including `pct`.

## Rolling out DMARC: none, quarantine, reject

> 

Start at `p=none` with a report address, fix every legitimate source the reports show failing, then move to quarantine and finally reject.

- Publish `v=DMARC1; p=none; rua=mailto:dmarc@example.com`. Delivery doesn't change; aggregate reports start arriving.
- Read the reports over a few weeks of normal sending. Every source that sends as you (your app, your email provider, your helpdesk, your billing tool) needs SPF or DKIM to pass for a domain aligned with your From address.
- Fix or move the sources that fail. A tool that can't sign with your domain can send from a subdomain you give it, with its own record.
- Publish `p=quarantine`. Mail that fails DMARC goes to spam.
- Publish `p=reject` once quarantine brings no surprises. Mail that fails DMARC is refused.

> **Forwarding and mailing lists:** Forwarding breaks SPF, and lists that add a footer or edit the subject break DKIM, so some legitimate mail fails DMARC through no fault of yours. Signing every message with DKIM for your own domain keeps most forwarded mail passing.

## Subdomains and the parent domain fallback

> 

When a subdomain has no DMARC record, receivers use the record on its organizational domain (the registered domain, such as `example.com` for `mail.example.com`), applying `sp=` if it is set and `p=` if not.

So one record at `_dmarc.example.com` covers every subdomain. Publish `_dmarc.mail.example.com` only when that subdomain needs a different policy. RFC 7489 finds the organizational domain with the Public Suffix List, and so does this checker; RFC 9989 replaces that with a DNS tree walk of at most eight queries, which reaches the same record for most domains.

## Sending reports to another domain

> 

When `rua` points at an address outside your organizational domain, the receiving domain has to publish a record agreeing to take your reports, or receivers won't send them (RFC 7489 §7.1).

The agreement is a TXT record at `<your domain>._report._dmarc.<their domain>` with the value `v=DMARC1`. A DMARC report service publishes it for its customers' domains. If the address is on another domain you run, publish it yourself:

**Authorization record**

```bash
example.com._report._dmarc.reports.example.net.  TXT  "v=DMARC1"
```

## Errors and how to fix them

### No DMARC record found

Also reported as: DMARC record missing; dmarc=none; DMARC policy not enabled

There is no TXT record starting with `v=DMARC1` at `_dmarc.<domain>`, or at its parent domain. Receivers apply no policy, and Gmail, Yahoo and Microsoft require a DMARC record from bulk senders; Gmail defers or rejects without one with `4.7.40` or `5.7.40`.

1. Publish a TXT record named `_dmarc` on the domain in your From address: `v=DMARC1; p=none; rua=mailto:dmarc@example.com`.
2. Use a report address you will read, or one from a DMARC report service.
3. Check again, then plan the move to quarantine and reject. The [DMARC generator](/tools/dmarc-generator) builds the record for you.

### Multiple DMARC records found

Also reported as: More than one DMARC record; DMARC permerror: multiple records

`_dmarc.<domain>` has more than one record starting with `v=DMARC1`. RFC 7489 tells receivers to apply no DMARC policy at all in that case, as if there were none.

1. List what DNS serves: `dig TXT _dmarc.example.com +short`.
2. Merge what you need into one record and delete the others.
3. Check again.

### Invalid DMARC record syntax

Also reported as: DMARC record has errors; DMARC syntax error; Invalid DMARC policy

A tag can't be read: no `p=`, a policy that isn't none, quarantine or reject, a `v=` that isn't exactly `DMARC1`, a `pct` outside 0 to 100, an alignment value other than `r` or `s`, or a report address without `mailto:`. Depending on the tag, receivers ignore it or discard the whole record.

1. Read the result line; it quotes the tag and says what's wrong.
2. Rewrite the record in this shape: `v=DMARC1; p=none; rua=mailto:dmarc@example.com`, with `v=DMARC1` first, a semicolon between tags and `mailto:` before every address.
3. Check again.

### DMARC record inherited from the parent domain

Also reported as: No DMARC record on subdomain; Subdomain DMARC policy

The subdomain has no record of its own, so receivers use the one on its organizational domain, with that record's `sp=` policy when it has one. That is normal and usually what you want.

1. Nothing to fix if the inherited policy suits this subdomain.
2. To give this subdomain a different policy, publish `_dmarc.<subdomain>` with its own `p=`.
3. To change the policy for every subdomain at once, set `sp=` on the parent record.

### DMARC policy is p=none

Also reported as: DMARC quarantine/reject policy not enabled; DMARC policy not enforced; DMARC monitoring mode

`p=none` asks receivers for reports and nothing more: mail that fails DMARC, spoofed mail included, is still delivered. It meets the bulk sender minimum and is the right first step, but it doesn't stop anyone sending as you.

1. Make sure the record has a `rua=` address and that reports are arriving.
2. Read a few weeks of reports and fix every legitimate source that fails.
3. Publish `p=quarantine`, then `p=reject`.

### DMARC pct below 100

Also reported as: DMARC policy applied to a percentage; pct tag less than 100

`pct` applies the policy to only part of the failing mail, and receivers treat the rest one step softer: quarantine becomes none, reject becomes quarantine. Receivers applied in-between values inconsistently, which is why RFC 9989 removed the tag. BIMI logos also need `pct` at 100.

1. Remove `pct` once you trust the policy; it defaults to 100.
2. If you aren't ready for the full policy, publish the step below it (`p=quarantine` instead of `p=reject`) rather than a partial one.

### No DMARC reporting address (rua)

Also reported as: DMARC rua tag missing; No DMARC aggregate reports

Without `rua=`, receivers send no aggregate reports, so you can't see which servers send as your domain or which of your own sources fail. Any move to quarantine or reject would be made blind.

1. Add `rua=mailto:dmarc@example.com` to the record.
2. Use a mailbox or report service that can take a steady flow of XML attachments, not a person's main inbox.
3. If the address is on another domain, that domain has to authorize it; see [sending reports to another domain](/tools/dmarc-checker#external-reports).

### External DMARC report destination not authorized

Also reported as: DMARC external destination verification failed; rua domain not authorized; _report._dmarc record missing

`rua` sends reports to a domain outside yours, and that domain hasn't published `<your domain>._report._dmarc.<their domain>`. Receivers check for that record before reporting to a third party, so your reports aren't sent there.

1. If the address belongs to a DMARC report service, check it matches what the service gave you; the service publishes the record for its customers.
2. If it is another domain you run, publish a TXT record at `example.com._report._dmarc.example.net` with the value `v=DMARC1`.
3. Or send reports to an address on your own domain.

### DMARC subdomain policy weaker than the main policy

Also reported as: sp=none with p=reject; Weak DMARC subdomain policy

`sp=` gives subdomains a softer policy than `p=`. Every subdomain without its own record gets the softer one, including names that don't exist, so a spoofer can send as `anything.example.com` and avoid your stricter policy.

1. Remove `sp=` so subdomains inherit `p=`, or set it to the same value.
2. Give a subdomain that still needs time its own record, such as `v=DMARC1; p=none; rua=mailto:dmarc@example.com` at `_dmarc.news.example.com`.

## Run this check without a browser

The page runs these lookups in the browser. An agent or script can run the same ones over public DNS-over-HTTPS (JSON answers; Cloudflare's `https://cloudflare-dns.com/dns-query` works too, with `accept: application/dns-json`):

1. Read the policy: `GET https://dns.google/resolve?name=_dmarc.example.com&type=TXT` and keep the answer that starts with `v=DMARC1`. With none at a subdomain, read the organizational domain's record instead.
2. Read `p` (none, quarantine or reject), `sp` for subdomains, `pct`, `adkim`, `aspf` and `rua`. More than one record is an error and receivers ignore all of them.
3. For a `rua` address on another domain, that domain must publish `v=DMARC1` at `example.com._report._dmarc.<their-domain>`, or reports aren't sent there.

For a sending domain in a Unitpost workspace, the MCP tool `email_domains_diagnose` checks every record Unitpost expects, on each of the domain's nameservers.

## FAQ

### What is the best DMARC policy?

`p=reject`, once your reports show every legitimate source passing. Get there through `p=none` and `p=quarantine`, because moving too early sends your own unaligned mail to spam or gets it refused.

### Does p=none protect my domain from spoofing?

No. It asks for reports and changes nothing about delivery, so spoofed mail is still delivered. It does meet the minimum Gmail, Yahoo and Microsoft set for bulk senders.

### Where do I put the DMARC record?

In a TXT record named `_dmarc` on the domain in your From address, so it resolves at `_dmarc.example.com`. Most DNS editors add the domain for you, so enter just `_dmarc` as the name.

### Do I need a DMARC record for every subdomain?

No. Subdomains without a record use the parent domain's, with its `sp=` policy if set. Publish one on a subdomain only when it needs a different policy.

### Why am I not getting DMARC reports?

The record may have no `rua=`, the address may be on another domain that hasn't authorized it, or not enough time has passed: aggregate reports usually cover a full day. Some receivers send no reports at all.

### Does Unitpost require DMARC to send?

No. Unitpost sends from a verified domain without a DMARC record, but the domain page shows one to add, starting at `p=none`, because Gmail and Yahoo require it from bulk senders.

## Related

- [Look up a DKIM record](https://www.unitpost.com/tools/dkim-checker): Look up a DKIM public key by selector and check its type, size and flags. Leave the selector empty to try common ones, and see the fix for each problem.
- [Generate a DMARC record](https://www.unitpost.com/tools/dmarc-generator): Build a DMARC record: pick a policy, a subdomain policy and a report address, then copy the value and publish it as a TXT record at _dmarc on your domain.
- [Analyze email headers](https://www.unitpost.com/tools/email-header-analyzer): Paste a message's headers to see its SPF, DKIM and DMARC results, alignment, unsubscribe headers and the delay at each hop. Nothing leaves your browser.
