This error is exactly what it says: a checker queried _dmarc.<your-domain> for TXT records and got nothing usable back. That could mean you never published DMARC, or that you published it in the wrong place, in the wrong format, or twice. All four are common, and all four look identical from the outside.
Where does a DMARC record actually live?
DMARC is a TXT record at the subdomain `_dmarc` of the domain you are protecting. For example.com, the full name is _dmarc.example.com. There is no DMARC record type — it is an ordinary TXT record whose value begins with v=DMARC1.
You can confirm what is published in one command. This is the same query every DMARC checker makes:
dig +short TXT _dmarc.example.com
# Compare against a domain that definitely has one:
dig +short TXT _dmarc.google.com
"v=DMARC1; p=reject; rua=mailto:[email protected]"If dig +short prints nothing, there is no record. If it prints something that does not start with v=DMARC1, the record exists but will be ignored — DMARC parsers require that exact tag, in that exact case, as the first tag.
What should the first record say?
Publish a monitoring-only record first. It satisfies every "DMARC not found" check, changes nothing about how your mail is handled, and starts the flow of aggregate reports you need before tightening the policy.
Type: TXT
Name: _dmarc
TTL: 3600
Value: v=DMARC1; p=none; rua=mailto:[email protected]; fo=1v=DMARC1— the version tag. Required, must be first, and is case-sensitive.p=none— the policy for the organizational domain.nonemeans "take no action, just report".rua=mailto:...— where daily aggregate (XML) reports are sent. Without this you get a valid record but no visibility, which defeats the point.fo=1— request a failure report when any authentication mechanism fails, rather than only when everything fails. Optional, and only meaningful if you also publishruf=.
Tags you can add later once you understand your mail flows: sp= (a separate policy for subdomains), adkim=/aspf= (strict vs relaxed alignment, relaxed by default), and pct= (what share of mail the policy applies to). Do not add pct= while you are at p=none — it does nothing there. The DMARC record generator will assemble a syntactically valid record for you if you would rather not hand-write it.
Why start at p=none?
A DMARC policy of quarantine or reject tells receiving mail servers to act on messages that fail authentication *and alignment*. Almost every organization has at least one legitimate sender nobody remembers — a billing system, a helpdesk, a CRM, an old marketing tool — that is not covered by SPF or DKIM. Publishing an enforcing policy before you find those senders is how invoices stop arriving.
p=none costs nothing and buys you the aggregate reports that name every IP sending as your domain. Read them for a few weeks, fix alignment for each legitimate sender, then move up. The staged path is covered in detail in p=none vs quarantine vs reject.
p=none still satisfies the "has DMARC" requirement that bulk-sender programs at Google, Yahoo, and Microsoft check for. Enforcement level is a separate question — see DMARC policy not enabled.What makes a published record still show as "not found"?
Five publication mistakes account for nearly all of them.
| Mistake | What it looks like | Fix |
|---|---|---|
| Wrong host name | Record created at @, example.com, or _dmarc.example.com.example.com | Enter just _dmarc in the Name/Host field on providers that append the zone automatically |
| Double-appended domain | dig TXT _dmarc.example.com empty, but _dmarc.example.com.example.com answers | Delete and re-add with the bare _dmarc label |
| Two DMARC records | Two TXT records at _dmarc both starting v=DMARC1 | Delete one. Per RFC 7489 receivers must discard the domain’s policy entirely when multiple v=DMARC1 records exist |
| Literal quotes in the value | Record renders as ""v=DMARC1; p=none"" | Most panels add the quoting themselves — paste the value without surrounding quotes |
| Wrong record type | Created as CNAME, SPF, or a "DMARC" custom type that the panel stores oddly | DMARC is always a plain TXT record |
The double-append case is the one that catches people repeatedly. Cloudflare, Namecheap, and most registrar panels take a relative label and append the zone; a few others want the fully-qualified name. If you are unsure which yours does, publish it, then verify with dig rather than trusting the panel’s preview. See Add a DMARC record on Cloudflare or Add a DMARC record in cPanel for the field-by-field version.
How do I verify it after publishing?
Query it three ways: against your own resolver, against a public resolver, and against the authoritative nameservers. If the authoritative answer is correct and the public resolvers disagree, you are just waiting out a cached negative answer.
# Default resolver
dig +short TXT _dmarc.example.com
# A public resolver, bypassing your local cache
dig @1.1.1.1 +short TXT _dmarc.example.com
# Straight from an authoritative nameserver
dig @$(dig +short NS example.com | head -1) +short TXT _dmarc.example.com
# host(1) works too, if dig is not installed
host -t TXT _dmarc.example.comThe delay between publishing and a checker seeing the record is the negative-cache TTL from your zone’s SOA record, not the TTL you set on the DMARC record itself. If a resolver already asked for _dmarc.example.com and got NXDOMAIN, it remembers that answer for the SOA minimum. That is usually 300–3600 seconds, so give it an hour before assuming the publish failed. You can watch it roll out globally with the propagation checker, and see every TXT record on the domain at once with the TXT record lookup.
_dmarc.example.com does nothing for mail sent as @mail.example.com unless you also cover subdomains — either publish a record there, or rely on sp= in the organizational-domain record.What to check alongside DMARC
A DMARC record on its own authenticates nothing — it is a policy statement about SPF and DKIM results. Before you raise the policy, confirm the underlying records are healthy:
- SPF exists, is a single record, and is under the 10-lookup limit — check with the SPF checker, and see SPF PermError: too many DNS lookups if it is not.
- DKIM is signing with a key you can resolve — the DKIM checker will find the selector if you do not know it.
- Your MX records point where you think they do — MX lookup.
- Your sending IP has a matching PTR record — reverse DNS lookup.
- Run all of it at once with the deliverability test.