DMARC: setup, policies, and fixing common problems
How DMARC tells receivers what to do with mail that fails SPF and DKIM, how to go from p=none to reject, and how to fix a broken record.
DMARC is a DNS record that tells mail servers what to do with a message that claims to come from your domain but fails SPF and DKIM: deliver it, put it in spam, or reject it. It also asks them to send you reports, so you can see every service sending mail as your domain, including ones that shouldn’t be.
Without it, anyone can send mail that looks like it’s from your domain, and each receiver decides on its own what to do. Gmail has required DMARC from anyone sending it more than 5,000 messages a day since February 1, 2024, and other large mailbox providers set similar rules.
What SignalDNS checks
We look up the TXT record at _dmarc. followed by your domain, such as _dmarc.example.com. If the name you entered has no record of its own, we check each parent domain in turn, as receivers do under RFC 9989, so a subdomain picks up its parent’s policy. A name with more than one DMARC record is skipped, because receivers discard them all.
From the record we read the policy (p=, or sp= when it comes from a parent), whether it’s in test mode (t=y), the older pct= tag, and where reports go (rua=). We don’t send mail, so we can’t see whether your mail actually passes; DMARC reports tell you that.
What a DMARC record looks like
_dmarc.example.com. TXT "v=DMARC1; p=quarantine; rua=mailto:[email protected]"
v=DMARC1must come first, exactly like that.p=is the policy for mail that fails:none(deliver it, and report),quarantine(treat it as suspicious, usually spam), orreject(refuse it).rua=is where receivers send daily summary reports. Use amailto:address; a DMARC reporting service gives you one that turns the reports into charts.sp=sets a different policy for subdomains, andnp=one for subdomains that don’t exist.t=yis test mode: receivers apply one step less than the policy while you check the reports.
There’s no DMARC record
Nothing is published at _dmarc. for the domain or any parent. Receivers get no instructions for mail that fails SPF and DKIM, and you get no reports, so you won’t know if someone is sending mail as your domain.
How to fix it: add a TXT record named _dmarc (your DNS provider adds the domain) with a monitoring-only policy and a report address:
v=DMARC1; p=none; rua=mailto:[email protected]
p=none doesn’t change how any mail is delivered, so it’s safe to add straight away. Read the reports for a few weeks, then move to enforcement.
DMARC is monitoring only (p=none)
p=none asks receivers to deliver mail that fails, and to report it. That’s the right first step, and SignalDNS marks it OK, but it doesn’t protect your domain: a forged message is still delivered. Once the reports show your own services pass, move to quarantine and then reject.
DMARC names no report address
The record has no rua= tag, so receivers have nowhere to send reports. With p=none that means the record does nothing visible: mail is delivered as before, and you never hear what failed.
How to fix it: add rua=mailto: and an address you read, or one from a DMARC reporting service. Reports for another domain’s address need that domain’s permission, which reporting services set up for you.
The DMARC record is broken or has a mistake
Receivers ignore a DMARC record they can’t read, which leaves the domain as if it had none. The usual causes:
- Two DMARC records. Receivers discard both. Merge them into one.
- It doesn’t start with
v=DMARC1. That tag must come first, with no space before it. - An unknown policy, such as
p=block. Under RFC 9989, a record with an invalid policy is read asp=noneif it has a report address, and ignored if it doesn’t. - Curly quotes or extra quote marks copied from a document. DNS providers add the quotes TXT records need.
- A report address without
mailto:.
When the record has a mistake but still has a usable policy, SignalDNS names the mistake and says what receivers will do instead.
Test mode (t=y)
t=y tells receivers you’re still testing: with p=reject they quarantine failing mail instead, and with p=quarantine they deliver it. It replaced pct= in RFC 9989. Remove t=y once the reports look right.
The pct tag
pct= comes from the older DMARC standard, RFC 7489, which RFC 9989 replaced in 2026. It asked receivers to apply the policy to only that percentage of failing mail. Some receivers still read it, so pct=10 with p=reject may mean most forged mail gets through. Use t=y while testing, and drop pct= once you enforce.
The policy comes from a parent domain
The name you checked has no DMARC record of its own, so receivers use its parent’s, such as example.com’s for mail.example.com. If the parent sets sp=, that’s the policy for its subdomains; otherwise p= applies. That’s usually what you want. Publish a record at _dmarc. plus the subdomain only if it needs a different policy.
Moving from p=none to reject
- Publish
p=nonewith a report address, and wait a week or two for reports. - In the reports, find every service that sends your mail: your mailbox provider, newsletters, invoicing, support tools. Make each one pass SPF or DKIM for your domain, usually by adding its include to your SPF record and turning on DKIM signing in its settings.
- Change to
p=quarantine, witht=yif you want a softer start, and keep reading reports. - When nothing legitimate fails, change to
p=reject.
Setting it up with your provider
- Google Workspace: set up DMARC
- Microsoft 365: set up DMARC
- Cloudflare: DMARC Management, which also collects your reports
- Namecheap: add TXT, SPF, DKIM, and DMARC records
What we can’t tell from outside
We read the published record. We can’t see your reports, so we can’t tell whether your own mail passes, and we don’t send test messages. A record that’s correct here can still let forged mail through if your policy is none, or block your own mail if a service you use isn’t set up for SPF or DKIM.
Sources
- RFC 9989: Domain-based Message Authentication, Reporting, and Conformance (DMARC)
- RFC 7489, the earlier standard, for
pct= - Google: email sender guidelines
Last reviewed .