2026年11月14日
2026年11月14日
How to Check SPF, DKIM and DMARC: dig Lookups and Email Headers
This article is a localized edition of the Japanese original. Read the Japanese original
SPF, DKIM and DMARC let a receiving mail server check whether the sending domain of a message has been spoofed. If they are missing or misconfigured, mail sent from your own domain can land in spam or be rejected outright.
This article shows how to check all three in DNS and in message headers. The record syntax follows RFC 7208 (SPF), RFC 6376 (DKIM) and RFC 7489 (DMARC), and the Gmail sender requirements reflect Google's "Email sender guidelines" as of October 2026. Replace example.com with your own domain.
How the three mechanisms differ
| Mechanism | What it checks | Where it lives in DNS | Domain it applies to |
|---|---|---|---|
| SPF | Whether the IP address of the sending server is allowed to send for the domain | TXT on the domain itself (example.com) |
Envelope sender (the Return-Path domain) |
| DKIM | Whether the digital signature on the message is valid (the message was not altered in transit) | TXT at セレクター._domainkey.example.com (selector._domainkey) |
The d= domain of the signature |
| DMARC | Whether SPF or DKIM passed in a way that aligns with the From: domain, and what to do on failure |
TXT at _dmarc.example.com |
The From: header domain |
SPF and DKIM each check a different domain, so passing either one does not prove that the From: domain the recipient sees is genuine. DMARC closes that gap by requiring the domain that passed SPF or DKIM to match the From: domain (alignment).
Before you start
List every service that sends mail for your domain: your own mail server, Google Workspace or Microsoft 365, newsletter services, and any web server (such as WordPress) that sends contact-form mail. SPF has to cover all of them, and DKIM signing is configured separately for each service.
Use dig to query DNS. It is in the bind9-dnsutils (or dnsutils) package on Debian / Ubuntu and in bind-utils on RHEL-based systems. On Windows, nslookup -type=TXT ドメイン名 (replace with your domain name) shows the same information.
Check SPF
dig +short TXT example.com
This lists every TXT record on the domain. The one that starts with v=spf1 is the SPF record.
"v=spf1 ip4:203.0.113.10 include:_spf.google.com -all"
| Syntax | Meaning |
|---|---|
ip4:203.0.113.10 / ip6:... |
Mail may be sent from this IP address (or range) |
a / mx |
Mail may be sent from the servers in this domain's A / MX records |
include:_spf.google.com |
Also allow the servers listed in that domain's SPF record (used for external services) |
-all |
Any server not matched above fails (fail) |
~all |
Any server not matched above is "probably unauthorized" (softfail) |
?all |
No verdict (neutral) |
You can check what an include: points to the same way, for example dig +short TXT _spf.google.com.
Common SPF mistakes
- More than one
v=spf1record. A domain can have only one SPF record. With more than one, the result is an error (permerror). When you add a service, add aninclude:to the existing record instead of creating a new one. - More than 10 DNS lookups.
include,a,mx,ptr,existsandredirecteach trigger a DNS lookup, and if the total, including those inside included records, exceeds 10, the check errors out. Removeinclude:entries for services you no longer use. - A sending server is missing. This often happens when a web server sends form mail. Add that server's IP address with
ip4:, or route the mail through a mail server that is already authorized. - Checking the wrong domain. SPF checks the envelope sender (the
Return-Path:header of the received message), notFrom:. Some sending services use their own domain inReturn-Path.
Check DKIM
The DKIM public key is published as a TXT record at セレクター._domainkey.ドメイン (selector._domainkey.domain). The selector is a name chosen by each sending service, so you cannot look it up from the domain alone.
Find the selector
Send a message from your domain, open it on the receiving side, and look at the DKIM-Signature: header.
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com; s=default; ...
d= is the signing domain and s= is the selector. In this example the public key is at default._domainkey.example.com. If there is no DKIM-Signature: header, the message was not DKIM-signed; turn on signing in the sending service.
Check the public key record
dig +short TXT default._domainkey.example.com
"v=DKIM1; k=rsa; " "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..."
- The value after
p=is the public key. Long keys are shown split into several strings like"..." "..."; receivers join them into one, so this is fine. - If
p=is empty (p=;or ending inp=), the key has been revoked. - If nothing is returned, the selector or domain is wrong, or the record has not been published yet.
- With Microsoft 365 and similar services,
selector1._domainkeyis a CNAME pointing to a record on the provider's side.digfollows the CNAME and shows the TXT.
Google requires DKIM keys of at least 1024 bits and recommends 2048 bits.
If you run OpenDKIM on your own server
OpenDKIM's opendkim-testkey (in the opendkim-tools package on Debian / Ubuntu) checks that the public key in DNS matches the private key on the server.
sudo opendkim-testkey -d example.com -s default -k /etc/opendkim/keys/example.com/default.private -vvv
key OK means they match. key not secure only means the record is not protected by DNSSEC and does not affect signature verification. Adjust the private key path to match your OpenDKIM configuration.
Check DMARC
dig +short TXT _dmarc.example.com
"v=DMARC1; p=none; rua=mailto:dmarc-reports@example.com"
If nothing is returned, DMARC is not set up. The main tags are:
| Tag | Meaning |
|---|---|
p= |
What to do with failing mail: none (do nothing, monitor only), quarantine (treat as spam), reject (refuse delivery) |
sp= |
Policy for subdomains. Defaults to the p= value |
rua= |
Where to send aggregate reports. Receiving servers send pass/fail summaries as XML |
ruf= |
Where to send per-message failure reports (many receivers do not send them) |
pct= |
Percentage of mail the policy applies to. Defaults to 100 |
adkim= / aspf= |
Alignment mode: r (relaxed, the default) or s (strict) |
If a subdomain (such as news.example.com) has no _dmarc record, the DMARC record of the organizational domain (example.com) is used and sp= applies.
What alignment means
To pass DMARC, one of these must be true:
- SPF passes, and the SPF domain (the
Return-Pathdomain) matches theFrom:domain - DKIM passes, and the signature's
d=domain matches theFrom:domain
In r (relaxed) mode, domains match if they share the same organizational domain, such as mail.example.com and example.com. In s (strict) mode, the domains must be identical.
With an external sending service, SPF often does not align because Return-Path uses the service's domain. You can still pass DMARC by setting up DKIM signing with your own domain (d=example.com) in that service.
Tightening the policy step by step
Jumping straight to p=reject means mail from any service you forgot to list will stop being delivered. Start with p=none and rua= to collect aggregate reports, confirm that every legitimate sender passes, and then move to p=quarantine and finally p=reject.
Verify results on a received message
Correct DNS records do not guarantee that real messages pass. Send a message from your domain to a Gmail address and check the result on the receiving side.
In Gmail, open the message, click "More" (the three vertical dots) at the top right, and choose "Show original". The SPF, DKIM and DMARC results appear at the top as PASS, FAIL and so on.
The Authentication-Results: header records the details, like this:
Authentication-Results: mx.google.com;
dkim=pass header.i=@example.com header.s=default header.b=AbCdEfGh;
spf=pass (google.com: domain of info@example.com designates 203.0.113.10 as permitted sender) smtp.mailfrom=info@example.com;
dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=example.com
| Field | What to look at |
|---|---|
spf= |
Is it pass? smtp.mailfrom= is the domain SPF checked |
dkim= |
Is it pass? header.i= / header.s= are the signing domain and selector |
dmarc= |
Is it pass? header.from= is the From: domain; p= is the policy applied |
As a rule of thumb: spf=softfail or spf=fail means the sending server is not in SPF; dkim=fail points to a key mismatch or a modified body; dkim=none means there is no signature; and dmarc=fail means neither SPF nor DKIM passed in alignment with the From: domain.
Gmail sender requirements
Since February 2024, Google requires everyone sending to personal Gmail accounts to set up SPF or DKIM. Senders of more than 5,000 messages a day must have SPF, DKIM and DMARC, with the From: domain aligned with the SPF or DKIM domain. For these senders a DMARC policy of p=none is acceptable. All senders must also have valid forward and reverse DNS, send over TLS and keep the spam complaint rate below 0.3%, among other requirements, and bulk senders must offer one-click unsubscribe for marketing mail.
Checking mail sent from WordPress
By default, WordPress contact-form and notification mail is sent directly from the web server. Even if From: uses your domain, the message can fail DMARC because the sending IP address is not in SPF, there is no DKIM signature, or Return-Path is the server's hostname.
Send a form message to yourself and check Authentication-Results: as described above. If it fails, the usual fix is to use an SMTP plugin so mail goes out through an authenticated mail server that has DKIM signing and SPF set up.
Summary
- Check SPF with
dig +short TXT example.com, DKIM withdig +short TXT セレクター._domainkey.example.com(use your selector), and DMARC withdig +short TXT _dmarc.example.com - Find the DKIM selector in the
s=value of theDKIM-Signature:header on a received message - SPF: one record per domain, at most 10 DNS lookups
- DMARC requires the SPF or DKIM domain to align with
From:; for external services, DKIM signing with your own domain is the key - Do the final check on the
Authentication-Results:header of a real message - Start DMARC at
p=noneand tighten it once you have checked the reports
Related articles:
- How to set up an SPF record
- How to set up DKIM signing with OpenDKIM
- How to move DMARC to p=reject
- What to do when WordPress does not send email
Questions about WordPress? The publisher of this site is based in Japan and replies in Japanese. Contact (Japanese)