Email authentication

How to check SPF, DKIM and DMARC on your own domain

The exact DNS queries to run, how to read the answers, and the misconfigurations that pass a casual look but fail in production.

RKS Infra Solutions7 min read

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.com

SPF 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:

  1. Exactly one SPF record. Two records beginning v=spf1 is 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.
  2. The DNS lookup count. Each include, a, mx, ptr, exists and redirect consumes one of ten permitted lookups, and includes nest — _spf.google.com alone expands to several. Exceed ten and the result is permerror. ip4, ip6 and all cost nothing.
  3. The final qualifier. -all means anything not listed is unauthorised. ~all is a soft fail. +all authorises the entire internet to send as your domain, and exists almost exclusively by accident.
  4. 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.com

There 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-Signature header of a message you have actually sent, as the s= 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.com

Always 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. none monitors and asks receivers to do nothing. quarantine asks for the message to go to junk. reject asks for it to be refused outright.
  • sp= — policy for subdomains. If absent, subdomains inherit p=. Worth setting explicitly to reject on 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=none for years. Monitoring mode protects nobody. It is the first step, not the destination.
  • rua pointing 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 rua to an address at another domain requires that domain to publish a record at yourdomain.com._report._dmarc.theirdomain.com. Without it, conforming receivers will not send the reports at all.
  • Strict alignment set without checking. aspf=s breaks 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

Want to know where your domain stands today?

The free email health check reads your live SPF, DKIM and DMARC records and explains what each one is currently doing. Start there, then bring us the parts that need a decision.