A DMARC record is published, but receivers discard it
What it is
There is a TXT record at _dmarc.example.cz, but its version tag is not exactly v=DMARC1. Receiving servers skip a record like that and treat the domain as if it had no DMARC at all.
That is why the scan does not tell you the record is missing — you can see it in your DNS. It tells you receivers will not use it. The effect is the same as a missing record: nobody enforces anything, and no reports arrive.
Which shapes these are
It is always about the start of the record, never about the p= policy that follows it. There are two groups.
Shapes the standard orders receivers to ignore
RFC 9989 section 4.7 requires the v= tag to come first and to have the value exactly DMARC1; otherwise the receiver must ignore the whole record.
v=dmarc1; p=reject— the value written in lower case.v=DMARC10; p=reject— something appended afterDMARC1.p=reject; v=DMARC1— the version tag placed after the policy.v=DMARC1; p=none— the record starts with a space. This usually comes from pasting a value out of a guide into a DNS panel.v=DMARC1 p=reject— no semicolon after the version, so the version value is the whole ofDMARC1 p=reject.v=DMARC2; p=reject— a version that does not exist; the only version there has ever been isDMARC1.
Shapes the standard allows, yet servers discard anyway
Here we have to be precise: under the grammar in section 4.8 these two are fine. Even so, three of the four widely used implementations whose source we read in September 2026 (OpenDMARC, rspamd, go-msgauth, Mail::DMARC) discard them — the filter they apply to the DNS answer is stricter than their own tag parser.
V=DMARC1; p=reject— a capitalVin the tag name.v = DMARC1; p=reject— whitespace around the=.
So we are not claiming the standard forbids them. We are claiming the protection does not hold in practice — and the fix is one character.
Why this is worse than having no record
- False comfort. Your DNS shows
p=reject, so the domain looks protected. Spoofed mail keeps going through. - No reports. The
rua=address is part of the record the receiver threw away, so you never learn about the spoofing. - The repair trap. A guide saying “add a DMARC record” leads you to publish a second TXT record next to the one you already have. RFC 9989 section 4.10 says that when the
_dmarcname holds two records, neither applies. You end up worse off than you started.
How to fix it
Fix the existing record; do not add a new one.
- Print what is published:
dig +short TXT _dmarc.example.cz(on Windows,nslookup -type=TXT _dmarc.example.cz). - Edit that one record in your DNS panel. Leave everything after the version tag alone — the policy,
rua=and the other tags. - Save it and wait for the TTL to expire (typically minutes to hours).
wrong: v=dmarc1; p=quarantine; rua=mailto:dmarc@example.cz
correct: v=DMARC1; p=quarantine; rua=mailto:dmarc@example.czWatch out for the two things the DNS editor adds to the value rather than you: a leading space, and extra quotes inside the value. So after saving, always read the record back with dig, not from the form.
Verification
When dig returns exactly one record starting with v=DMARC1;, you are done. You can confirm it with a fresh scan at vulscan.app — the DMARC check is part of the free scan.
Only then is it worth working on the strength of the policy: what p=none, p=quarantine and p=reject mean and in which order to roll them out is covered in Domain has no DMARC record.
References
- Vulscan docs: DMARC from scratch
- Vulscan docs: SPF
- RFC 9989 — DMARC — section 4.7 (version tag), 4.8 (record grammar), 4.10 (two records = none applies)