Fast diagnostic checklist
Work these six checks in order before digging deeper.
-
Read the live record. Query
_dmarc.yourdomain.comfrom a public resolver (commands below) and confirm you get exactly onev=DMARC1record with arua=tag. -
Validate rua= syntax. Every address must start with
mailto:, multiple addresses are comma-separated, and tags are semicolon-separated. One wrong character silences all reports. -
Check for an external authorization record. If the report mailbox is on a different organizational domain than the policy domain, the external domain must publish a
_report._dmarcTXT record (see Cause 2 below). If you use a hosted DMARC service such as DMARCTrust, the authorization record for your domain is created automatically when you add the domain, so you can skip to step 4. - Confirm real mail volume. A domain sending fewer than a handful of messages per day may genuinely receive no reports, because receivers only report on mail they have evaluated.
- Wait 24 to 48 hours. Most receivers send reports once per UTC day; some send more often. A record published this morning will not produce a report until the following day.
- Confirm the mailbox accepts large attachments. Aggregate reports are gzip or zip attachments that can reach several megabytes for high-volume domains. A mailbox that is over quota or has a size limit will bounce the report silently.
Not receiving DMARC reports: read the record first
DMARC aggregate reports flow because a domain publishes a rua= tag in its _dmarc TXT record, and receiving mail servers send a daily XML summary to that address. When reports stop arriving, the cause is almost always one of: the rua= URI is malformed, the report mailbox lives on a different domain and the required authorization record is missing, there is no mail volume to report on, or the receiving mailbox is rejecting the reports. Work through them in that order.
Start by reading the record exactly as the world sees it. DMARC is published at the _dmarc label of the visible From: domain (RFC 9989 section 4.1):
dig +short TXT _dmarc.example.com
dig +short TXT _dmarc.example.com @1.1.1.1
dig +short TXT _dmarc.example.com @8.8.8.8
On Windows, use nslookup instead:
nslookup -type=TXT _dmarc.example.com 1.1.1.1
The @1.1.1.1 and @8.8.8.8 arguments (or the equivalent resolver IP in nslookup) query Cloudflare and Google directly so you see the published value rather than a stale local cache. You should get back exactly one record beginning with v=DMARC1 that contains a rua= tag.
Cause 1: the rua URI is malformed
The rua= value is a comma-separated list of DMARC URIs, and each one must be a full URI with the mailto: scheme (RFC 9989 section 4.7). A missing scheme or the wrong separator silently breaks report delivery. These are the failures that look right but are not:
# Wrong - missing the mailto: scheme
v=DMARC1; p=none; [email protected]
# Wrong - comma used as the tag separator instead of semicolon
v=DMARC1, p=none, rua=mailto:[email protected]
# Wrong - semicolon between two report addresses (should be a comma)
v=DMARC1; p=none; rua=mailto:[email protected];mailto:[email protected]
# Correct - mailto: on every address, addresses comma-separated, tags semicolon-separated
v=DMARC1; p=none; rua=mailto:[email protected],mailto:[email protected]
The separator rule is the one people get wrong most often: tags are separated by semicolons, but multiple addresses inside a single rua= are separated by commas. Also check for smart quotes pasted from a document, trailing spaces, and a DNS provider that wrapped the value across fields. Regenerate a clean record with the DMARC record generator if you are unsure of the syntax.
Cause 2: missing external authorization record
This is the cause most people miss. If your rua= mailbox is on a domain whose organizational domain differs from the domain that published the DMARC policy, the receiving mail server will not send reports until the external domain publishes a record authorizing it. This external destination verification is defined in RFC 9990 section 4, and it exists so that a domain cannot name your mailbox as a report sink without your consent.
Concretely: if example.com publishes rua=mailto:[email protected], the organizational domains differ (example.com versus dmarctrust.com), so the receiver constructs and queries a verification record. The query name is built by prepending the literal string _report._dmarc to the external domain, then prepending the policy domain (RFC 9990 section 4):
<policy-domain>._report._dmarc.<external-domain>
You can query a live one. DMARCTrust creates an authorization record for each monitored domain rather than publishing a wildcard, and dmarctrust.com is itself a monitored domain:
dig +short TXT dmarctrust.com._report._dmarc.reports.dmarctrust.com @1.1.1.1
On Windows:
nslookup -type=TXT dmarctrust.com._report._dmarc.reports.dmarctrust.com 1.1.1.1
Both return "v=DMARC1". The external domain must answer with a TXT record that parses as DMARC tag-value pairs, with v=DMARC1 mandatory and first. The minimum valid content is just the version tag:
dmarctrust.com._report._dmarc.reports.dmarctrust.com. IN TXT "v=DMARC1"
RFC 9990 section 4 is explicit about the consequence of the record being absent or unparseable: "Where the above algorithm fails to confirm that the external reporting was authorized by the Report Consumer, the URI MUST be ignored by the Mail Receiver generating the report." No record means no report. A domain willing to receive reports for any policy domain can publish a wildcard instead:
*._report._dmarc.example.com. IN TXT "v=DMARC1"
If your reporting address is at a hosted DMARC service, the provider will tell you the exact authorization record to publish. With DMARCTrust your reporting address is on reports.dmarctrust.com, a domain we control, and we create the authorization record for your domain automatically when you add it to your account. You only need to worry about this cause when you point rua= at a mailbox on a domain you own but that is separate from the policy domain.
Cause 3: there is no mail to report on
Aggregate reports summarize messages a receiver evaluated against your DMARC policy. If the domain sends little or no mail to a given provider, that provider has nothing to summarize and sends no report. Parked domains, freshly registered domains, and domains used only for inbound mail commonly end up here.
Before assuming the record is broken, confirm the domain is actually sending mail that reaches reporting receivers. dmarcian notes that domains sending fewer than roughly 50 messages per day may wait days longer than usual for reports to arrive, or may see none at all from providers that only generate reports above a certain message threshold. This is a vendor observation rather than a spec requirement, but it holds up in practice: if your domain sends very little mail, a quiet reporting inbox is expected.
Cause 4: the report mailbox is bouncing or rejecting
Reports are delivered by email, so the report mailbox has to accept them. Aggregate reports are gzip or zip attachments and can be large for a high-volume domain. A mailbox that is over quota, that rejects attachments, or that has a size limit below the report size will bounce the report, and the sending receiver does not retry indefinitely.
Check that the rua= mailbox exists and accepts mail with attachments. If you control it, look at its inbound logs for messages from reporting senders that were rejected for size or quota. A dedicated mailbox or a hosted DMARC endpoint tends to sidestep this, because it is sized for report ingestion.
Cause 5: cadence and coverage expectations
Two expectations trip people up after they have ruled out configuration problems.
- Cadence is daily. RFC 9990 section 3.1 describes aggregate reports as "daily (or more frequent)" and the ri= interval tag from RFC 7489 was not carried forward into DMARCbis, so there is no configurable cadence. A record published this morning typically produces its first report the next day, not within minutes.
- Coverage is partial. Sending aggregate reports is voluntary. The table below shows what to expect from the major senders. Getting reports from only a few sources is expected behavior, not a fault.
-
Failure (ruf) reports are rare. A
ruf=tag requests failure reports with message-level detail. Microsoft 365 does not send them at all. Most other major providers have also stopped, largely for privacy reasons, so an empty failure-report feed is normal. Rely on aggregate data for your day-to-day view.
Who sends DMARC aggregate reports, and when
| Reporter | Sends aggregate (rua)? | Cadence | Notes |
|---|---|---|---|
| Google / Google Workspace | Yes | Once per day | Reports sent to all rua addresses. Google processes on UTC day boundaries. Source: Google Workspace DMARC reports help. |
| Microsoft 365 / Outlook.com | Yes, with a condition | Once per day (previous day's data) | Reports are only generated when the domain's MX record points directly to Microsoft 365. If a third-party filter (SEG, on-premises gateway) sits in front, Microsoft does not send reports for that domain. Microsoft does not send ruf reports at all. Source: Microsoft Learn: DMARC reports. |
| Yahoo / Yahoo Mail | Yes | Daily | Yahoo participates in aggregate reporting. Specific timing and sender address are not publicly documented on Yahoo's sender hub at the time of writing. |
| Most smaller receivers | Often no | Varies or never | Aggregate reporting is voluntary under the spec. Regional ISPs and smaller mail hosts frequently send no reports. This is a gap in coverage, not a configuration error on your part. |
The Microsoft MX condition is the most common explanation for "I get Google reports but not Microsoft." If your domain uses a third-party secure email gateway with MX pointing to that gateway rather than Microsoft 365, Microsoft will not generate aggregate reports regardless of your rua= tag.
Validate the fix
After you correct the record or publish the authorization record, wait at least one TTL, then re-check the live values from public resolvers:
dig +short TXT _dmarc.yourdomain.com @1.1.1.1
dig +short TXT yourdomain.com._report._dmarc.reports.dmarctrust.com @1.1.1.1
You want exactly one valid v=DMARC1 policy record with a well-formed rua=, and, if your report mailbox is on a separate domain, a matching authorization record that returns v=DMARC1. Use the DMARCTrust DMARC checker to confirm the published policy parses cleanly, then allow up to 48 hours for the first reports to arrive.
Once reports start flowing, the raw aggregate XML is tedious to read by hand. The DMARC reports dashboard turns the daily XML into a per-source view that shows the failing IP, the evaluated identity, and which alignment path to fix. If you are not yet collecting reports anywhere, create an account to get a hosted reporting address with the external authorization handled for you.
Related fixes
- If your record is still in monitoring mode, read DMARC policy not enabled.
- If lookups time out or return SERVFAIL intermittently, read DMARC temperror and DNS timeouts.
- If a DMARC lookup finds nothing at all, read no DMARC record found.
- If reports show passes but spoofing continues, read DMARC pass but spoofing continues.
- If reports show your ESP failing alignment, read ESP mail fails DMARC.