What SPF, DKIM, and DMARC do, why aligned SPF or DKIM is enough for DMARC, and how to grade your domain with a live checker.
Password entropy measures how hard a secret is to guess, in bits. Here is the formula, why Password1! fails it, and how to generate something strong.
9 min read
An IPv4 address is one 32-bit number. Here is how to read it as decimal, hex, binary or integer, size a CIDR block, and spot private ranges.
9 min read
SPF, DKIM, and DMARC are three DNS-published email authentication standards: SPF lists which servers may send mail for your domain, DKIM signs each message with a key you publish, and DMARC tells receivers what to do when mail claiming your domain fails those checks.
Want to see where your domain stands right now? Paste it into the free Email Security Checker. It fetches and grades the domain's SPF and DMARC records live, and checks DKIM when you supply a selector. The rest of this article explains what each record does, how DMARC decides pass or fail, the policy ladder from
p=nonetop=reject, and the misconfigurations that quietly break protection.
Plain SMTP never checks that a sender is who they claim to be. A message carries two "from" values: the envelope sender (MAIL FROM, used for bounces) and the From: header people see. Microsoft's email authentication overview shows how these can point at completely different domains, which is what makes spoofing, phishing, and business email compromise (BEC) possible.
SPF, DKIM, and DMARC exist to close that gap for your own domain. This article covers domain hygiene, anti-phishing, and BEC defense on domains you own or are authorized to assess. It is not a guide to sending bulk mail or impersonating anyone.
| Standard | Plain-language job | Where it lives in DNS | Current spec |
|---|---|---|---|
| SPF (Sender Policy Framework) | "These servers are allowed to send mail using my domain in the envelope sender." | TXT record at the domain itself, starting v=spf1 | RFC 7208 |
| DKIM (DomainKeys Identified Mail) | "This message was signed by someone holding my private key, and the signed parts were not changed in transit." | Public key in a TXT record at selector._domainkey.example.com | RFC 6376 |
| DMARC | "Check that SPF or DKIM passed for the domain in the visible From address, then apply my policy and send me reports." | TXT record at _dmarc.example.com, starting v=DMARC1 | RFC 9989 (May 2026) |
A note on the DMARC standard: for years it was RFC 7489. In May 2026 the IETF published RFC 9989 (core DMARC), RFC 9990 (aggregate reporting), and RFC 9991 (failure reporting), which together obsolete RFC 7489. Alignment, the none / quarantine / reject policies, and rua= reports all carry over.
SPF is a single TXT record listing the senders you authorize, ending in an all mechanism that sets the default for everyone else:
example.com. TXT "v=spf1 ip4:192.0.2.0/24 include:_spf.mailprovider.example -all"
The qualifier on all matters. Per RFC 7208, - means fail, ~ means softfail, ? means neutral, and + means pass. -all says "reject anything I did not list"; ~all says "probably not authorized" and is a common transition setting.
SPF has two limits. It checks the envelope sender, not the visible From: header. And because it is tied to the sending IP, it often breaks on forwarding: the forwarding server is not on your list.
DKIM adds a DKIM-Signature header to outgoing mail. The header names the signing domain (d=) and a selector (s=). Receivers fetch the public key from DNS and verify the signature. RFC 6376 gives the lookup rule directly: a signature with d=example.com and s=foo.bar is verified with the key at foo.bar._domainkey.example.com.
Selectors let one domain run several keys at once (per provider, or during key rotation). Your mail provider usually picks the selector name, and there is no standard way to list them, which is why the checker asks for one.
Because the signature travels with the message, DKIM usually survives forwarding where SPF does not.
DMARC ties the other two to the domain a human actually sees. A DMARC record looks like:
_dmarc.example.com. TXT "v=DMARC1; p=none; rua=mailto:dmarc-reports@example.com"
It requires alignment between the visible From: domain and a domain SPF or DKIM authenticated, states a policy for failures, and requests reports.
This is the part most people get wrong. DMARC does not require both to pass. RFC 9989 (section 5.3.5): if one or more authenticated identifiers align with the author domain, the message passes. RFC 7489 said the same: at least one mechanism must pass on an aligned identifier.
So DMARC passes when either of these is true:
From: domain.d= domain matches the From: domain."Matches" depends on the alignment mode. Relaxed alignment (the default for both aspf and adkim per RFC 9989 section 4.7) only needs the same organizational domain, so bounces.example.com aligns with example.com. Strict alignment needs an exact match.
Why alignment matters: SPF and DKIM on their own only prove that some domain authorized the mail. Microsoft's guide describes how a message can pass SPF or DKIM for an unrelated domain while showing your brand in From:. Alignment is what ties "authenticated" to "the domain the reader sees."
| Scenario | SPF (aligned?) | DKIM (aligned?) | DMARC |
|---|---|---|---|
| Direct send from your provider | Pass, aligned | Pass, aligned | Pass |
| Forwarded by a mail alias | Fail (forwarder IP not listed) | Pass, aligned | Pass |
| Third-party tool using its own bounce domain, no custom DKIM | Pass, not aligned | Pass, not aligned | Fail |
| Spoofed message from an unlisted server | Fail | None | Fail |
The forwarding row is why SPF alone is not enough. RFC 9989 (section 7.4) says relayed mail will most likely fail SPF while DKIM signatures generally stay valid, and that domains publishing p=reject must not rely solely on SPF.
| Policy | What it asks receivers to do | What it means in practice |
|---|---|---|
p=none | Nothing. RFC 9989 calls it "no expression of preference." | Monitoring mode. You get reports, but spoofed mail can still be delivered. RFC 9989 section 5.4 says p=none must not change existing mail handling. |
p=quarantine | Treat failing mail as suspicious | Usually spam folder or extra scrutiny |
p=reject | Treat failures as clear evidence the domain name was misused | A request to refuse the message, often during SMTP if the receiver rejects at all. Receivers must not reject solely because the policy is p=reject; without other analysis they treat it as quarantine (RFC 9989 §§7.4 and 8). |
rua= aggregate reports make the ladder safe to climb. Participating receivers send periodic XML summaries (RFC 9990) showing which IPs sent mail as your domain and whether SPF and DKIM passed and aligned. RFC 9989 recommends starting at p=none with rua= set, fixing every legitimate sender the reports reveal, then moving to enforcement. For domains whose users post to mailing lists, it suggests at least a month at none and as long again at quarantine before reject.
Two caveats from the spec:
p=reject.pct= is retired. RFC 9989 marks the old pct tag as historic and adds a t= testing flag. If your record still uses pct=, check RFC 9989 before relying on it.| Failure | What happens | Fix |
|---|---|---|
| Two SPF TXT records on the same name | RFC 7208 (section 4.5): more than one v=spf1 record produces permerror, so SPF breaks for every message. | Merge them into one record. |
| More than 10 DNS-lookup terms | RFC 7208 (section 4.6.4): include, a, mx, ptr, exists, and redirect count toward a limit of 10, nested includes included. Over the limit returns permerror. | Drop unused includes; prefer ip4/ip6 where sensible. |
+all (open SPF) | RFC 7208's own example says v=spf1 +all means any IP passes. The record authorizes the whole internet. | End with -all or ~all. |
| Missing or wrong DKIM selector | No key at selector._domainkey.yourdomain, a typo, or a stale selector after a provider change. DKIM can't verify, so it can't rescue forwarded mail. | Publish your provider's exact selector key; keep the old key until in-flight mail clears. |
DMARC stuck on p=none | Looks configured but enforces nothing. Spoofed mail can still land. | Read the rua= reports, align every legitimate sender, then move to quarantine and reject. |
No rua= | Under RFC 9989, receivers must not send aggregate reports if rua is absent, so you are flying blind. | Add a dedicated reporting mailbox or a report-processing service. |
| Method | Strengths | Blind spots |
|---|---|---|
| Andrax Email Security Checker | One paste grades SPF uniqueness, the 10-lookup limit, the all qualifier, and DMARC policy. DKIM is checked when you give a selector. | One domain at a time. It can't guess unknown DKIM selectors. It reads DNS, not your actual mail flow. |
dig TXT example.com / dig TXT _dmarc.example.com | Exact raw records. Scriptable for inventory. | You count lookups and spot duplicate records yourself, including inside nested includes. |
DMARC aggregate reports (rua=) | Show how real receivers evaluated your mail | Only exist if rua= is set. Raw XML needs a parser. |
For raw spot checks on a domain you own or are authorized to assess:
dig +short TXT example.com | grep -i "v=spf1"
dig +short TXT _dmarc.example.com
dig +short TXT selector1._domainkey.example.com # use your provider's real selector
When to use the Andrax tool: a quick hygiene grade on your own domain, a before-and-after check when you change SPF or DMARC, or showing a stakeholder why p=none is not "done." Use raw DNS to trace nested includes or automate checks across a portfolio.
Same-domain hygiene usually comes in a set:
~all (during transition) or -all.d= or a subdomain of it.p=none with a working rua= mailbox and review the reports.p=quarantine and later p=reject.v=spf1 -all (RFC 7208 gives this as the record for a domain that sends no mail) along with a DMARC policy.Yes. SPF and DKIM authenticate mail differently; DMARC links them to the visible From domain, sets enforcement, and enables reporting. RFC 9989 recommends using both SPF and DKIM.
No. It needs at least one of them to pass and align with the From domain. In practice DKIM is the more reliable path, because it survives forwarding.
Usually the policy is p=none (monitoring only). Otherwise the spoof uses a lookalike domain (DMARC covers only the exact domain), or the receiver chose not to apply your policy.
~all or -all better?-all is stronger once every legitimate sender is listed; ~all is a common step while you are still discovering senders. RFC 9989 notes some receivers act on an SPF -all fail before DMARC runs, which can reject mail DKIM would have saved. Another reason to deploy DKIM everywhere.
SPF says which servers may send, DKIM proves a message was signed by your domain and not altered, and DMARC requires at least one of them to pass and align with the visible From address, then applies your policy and sends reports. One clean SPF record under the lookup limit, DKIM on every sender, and DMARC past p=none make your domain a much harder target for phishing and BEC.
When you're ready to grade a domain you own, run it through the Email Security Checker on Andrax.
A TLS certificate binds a domain name to a public key. Here is how I read one, trace its chain, fix common errors, and check CSRs and CAA records.
11 min read