All three records are public DNS. You do not need access to the mail server to inspect them, and you do not need a tool — though ours will do the parsing and flag the problems for you.
The commands below use dig. On Windows, nslookup -type=TXT yourdomain.com gets you the same records with noisier output.
SPF
dig +short TXT yourdomain.comSPF has no record type of its own. It is a TXT record on the domain itself, beginning v=spf1, mixed in with your verification records and everything else:
"v=spf1 include:_spf.google.com include:sendgrid.net ~all"Four things to check:
- Exactly one SPF record. Two records beginning
v=spf1is a permanent error under RFC 7208, and most receivers will treat SPF as failing entirely. This happens constantly when a second platform is added and someone publishes a new record instead of editing the existing one. - The DNS lookup count. Each
include,a,mx,ptr,existsandredirectconsumes one of ten permitted lookups, and includes nest —_spf.google.comalone expands to several. Exceed ten and the result ispermerror.ip4,ip6andallcost nothing. - The final qualifier.
-allmeans anything not listed is unauthorised.~allis a soft fail.+allauthorises the entire internet to send as your domain, and exists almost exclusively by accident. - Every sender is covered. Your CRM, helpdesk, invoicing tool and marketing platform all send as you. Each needs to be in the record or signing with DKIM.
DKIM
DKIM is the awkward one, because the record lives at a selector you have to know in advance:
dig +short TXT selector._domainkey.yourdomain.comThere is no DNS query that lists every selector on a domain — DNS has no “show me what is under here” operation for this. You find the selector in one of two places:
- In the
DKIM-Signatureheader of a message you have actually sent, as thes=tag. - In the sending platform’s own documentation or DNS setup screen.
This is why a tool reporting “DKIM not found” for an arbitrary domain tells you almost nothing. It guessed at common selector names and none matched. The domain may be signing perfectly with a selector the tool never tried.
A valid record looks like:
"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A..."An empty p= means the key has been revoked. A key shorter than 1024 bits is too weak and some receivers ignore it; 2048 is the sensible default.
DMARC
dig +short TXT _dmarc.yourdomain.comAlways on the _dmarc subdomain, never the domain itself:
"v=DMARC1; p=reject; rua=mailto:dmarc@yourdomain.com; adkim=s; aspf=s"What the tags mean:
p=— the policy.nonemonitors and asks receivers to do nothing.quarantineasks for the message to go to junk.rejectasks for it to be refused outright.sp=— policy for subdomains. If absent, subdomains inheritp=. Worth setting explicitly torejecton domains whose subdomains never send mail.rua=— where aggregate XML reports are sent. Without this, DMARC is telling you nothing.adkim=/aspf=— alignment mode.r(relaxed, the default) accepts a subdomain match;s(strict) requires an exact domain match.pct=— applies the policy to a percentage of messages. Support for intermediate values is inconsistent between receivers and it is being phased out of the specification; treat it as a short-term rollout aid rather than a permanent setting.
The checks that a casual look misses
- A DMARC record that has sat at
p=nonefor years. Monitoring mode protects nobody. It is the first step, not the destination. ruapointing at an unmonitored mailbox. Aggregate reports arrive as gzipped XML, daily, from dozens of providers. If nobody parses them, the data is not being used.- Reports sent to a different domain without authorisation. Sending
ruato an address at another domain requires that domain to publish a record atyourdomain.com._report._dmarc.theirdomain.com. Without it, conforming receivers will not send the reports at all. - Strict alignment set without checking.
aspf=sbreaks any sender using a subdomain for the envelope, which is most of them.
Check from outside your own network
Query a public resolver rather than trusting your DNS provider’s dashboard — the dashboard shows what you intended, a resolver shows what the world sees, and propagation delays or a stale zone will make those differ:
dig @1.1.1.1 +short TXT _dmarc.yourdomain.com