Skip to content

/commands/dig/dig-txt-record-spf-dmarc

dig TXT: check SPF, DMARC and domain verification TXT records

The commands on this page have not been executed by our verification runner yet.updated
tool
dig / nslookup
versions
BIND 9.18, BIND 9.20
os
linux, macos, windows

dig example.com TXT +short prints every TXT record on a name, one record per line in double quotes. Mail and verification records live at fixed names: SPF on the domain itself, DMARC on _dmarc.DOMAIN, DKIM on SELECTOR._domainkey.DOMAIN, ACME DNS challenges on _acme-challenge.DOMAIN. Query the exact name, or you will see a different set of records.

bash
dig example.com TXT +short                   # all TXT records at the apex (SPF lives here)
dig _dmarc.example.com TXT +short            # DMARC policy
dig s1._domainkey.example.com TXT +short     # DKIM public key for selector "s1"
dig _acme-challenge.example.com TXT +short   # Let's Encrypt DNS-01 token

Where each record lives

RecordName to queryStarts with
SPFexample.comv=spf1
DMARC_dmarc.example.comv=DMARC1
DKIMSELECTOR._domainkey.example.comv=DKIM1 (the selector is in the s= tag of the DKIM-Signature header)
ACME DNS-01_acme-challenge.example.comA random token, no prefix
Site verificationUsually example.comA provider-specific string such as google-site-verification=...

Find the SPF record among many

The apex often carries several TXT records (verification strings for different services). Filter for the SPF one:

bash
dig example.com TXT +short | grep -i 'v=spf1'
dig example.com TXT +short | grep -ci 'v=spf1'   # must print 1

More than one v=spf1 record makes SPF evaluation fail with permerror (RFC 7208, section 4.5). SPF also limits DNS lookups caused by include, a, mx, ptr, exists and redirect to 10 per check (section 4.6.4); follow each include: with another dig TXT to count them.

Long values

DKIM keys exceed the 255-byte limit of a DNS character-string, so they appear as several quoted pieces on one line: "v=DKIM1; k=rsa; p=MIIB..." "...IDAQAB". That is one record; the receiver joins the pieces. Two separate lines, on the other hand, are two records.

Check propagation

After editing a record, ask the zone's authoritative server first, then a public resolver:

bash
dig example.com NS +short
dig @ns1.example.net _dmarc.example.com TXT +short
dig @8.8.8.8 _dmarc.example.com TXT +short

If the authoritative server shows the new value and the resolver the old one, wait for the TTL of the cached record to expire. If the authoritative server shows the old value, the change was not saved in the zone that is actually delegated. An empty answer with status: NOERROR in the full output means the name exists without TXT data; NXDOMAIN means the name does not exist, often a typo in _dmarc or the selector.

FAQ

Why is my TXT record split into several quoted strings?

A single DNS character-string holds at most 255 bytes, so longer values (DKIM keys, long SPF records) are stored as several strings in one record. Receivers concatenate them without spaces, so the split does not change the value.

Can a domain have two SPF records?

No. RFC 7208 says that if a domain publishes more than one TXT record starting with v=spf1, the SPF check returns permerror. Merge the mechanisms into a single record.

My provider asks for a TXT record on @. What name do I query?

@ means the zone apex, so query the bare domain, for example dig example.com TXT +short. Verification records on a subdomain such as _acme-challenge.example.com are queried by their full name.

Sources