Support Library
Email Phishing Protection: SPF, DKIM, DMARC
SPF, DKIM and DMARC are three DNS records that let receiving mail servers check whether a message claiming to be from your domain really came from you. DMARC ties the other two to the visible From address and tells receivers to reject or quarantine mail that fails.
The short answer
Email was designed without any proof of who sent a message. Anyone can connect to a mail server and type From: ceo@example.com, and the oldest phishing trick is to do exactly that with your domain. Three standards close that gap, and each one is published as a TXT record in your DNS zone:
- SPF, defined in RFC 7208, lists the servers allowed to send mail for a domain.
- DKIM, defined in RFC 6376, adds a cryptographic signature that receivers verify with a public key from DNS.
- DMARC, defined in RFC 9989, which replaced the original RFC 7489 in May 2026, requires one of those checks to pass for the same domain the reader sees in the From line, and publishes what to do when neither does.
Both check a domain, but not necessarily the one in the From line. An attacker can pass SPF and DKIM for a domain they own while showing yours. Only DMARC, with a policy of quarantine or reject, closes that gap.
How a message is checked when it arrives
When a message reaches your organization's mail gateway, the receiving server runs SPF and DKIM side by side, checks whether each result lines up with the From domain, and then applies DMARC. The diagram follows one message from 203.0.113.10 that claims to be from example.com.
Every receiver that supports DMARC follows this order, whether it is a large mailbox provider or your own gateway checking inbound mail. That is why the same three records protect both your customers, who receive mail claiming to be from you, and your staff, who receive mail claiming to be from partners and suppliers.
The three identities in every message
Most confusion about email authentication comes from the fact that a single message carries several domain names, and each standard looks at a different one.
| Identity | Where it lives | Checked by | Seen by the reader? |
|---|---|---|---|
| Envelope sender, also called MAIL FROM or Return-Path | The SMTP conversation; bounces go here | SPF | No |
| Signing domain, the d= tag | The DKIM-Signature header | DKIM | No |
| Header From | The From: header | DMARC, through alignment | Yes |
A newsletter platform might send your campaign with a MAIL FROM of bounces.mailer.example.net and a DKIM signature from mailer.example.net, while the From line shows news@example.com. SPF and DKIM both pass, but for the platform's domain, not yours. DMARC fails until the platform is set up to sign as example.com or to use a bounce domain under it.
SPF: which servers may send
An SPF record is a TXT record at the domain used in MAIL FROM. It lists the addresses and services allowed to send for that domain and ends with a default for everything else.
$ dig +short TXT example.com
"v=spf1 ip4:203.0.113.0/24 include:_spf.mailprovider.example -all"
The receiver evaluates the mechanisms from left to right and stops at the first match. ip4 and ip6 match address ranges, include pulls in another domain's SPF record, and the final all catches everything else. Its qualifier sets the result: -all is a hard fail, ~all is a soft fail, and +all authorizes the entire internet, which defeats the record.
- One record per name. Two TXT records starting with v=spf1 at the same name produce a permanent error, and receivers treat the domain as having no valid SPF.
- Ten DNS lookups at most. Each include, a, mx, exists and redirect counts, including those inside included records. Going over the limit is also a permanent error, and it is easy to hit after adding a few SaaS senders.
- Forwarding breaks SPF. When a mailbox forwards a message, the next hop sees the forwarder's IP, which your record does not list. That is one reason DKIM matters.
The TXT records guide covers how SPF shares the TXT type with other verification records, and SPF/DMARC Misconfigurations lists the mistakes that most often weaken it.
DKIM: a signature that survives forwarding
The sending system signs selected headers and the body with a private key and adds a DKIM-Signature header. The d= tag names the signing domain and s= names the selector, which tells the receiver where to find the public key:
DKIM-Signature: v=1; a=rsa-sha256; d=example.com; s=s1; h=from:to:subject:date; bh=…; b=…
$ dig +short TXT s1._domainkey.example.com
"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA…"
Because the signature travels inside the message, it still verifies after simple forwarding. It fails when something changes the signed content on the way, such as a mailing list that adds a footer or a gateway that rewrites links. Selectors let each sending service have its own key, so you can add or retire a provider without touching the others. Key sizes, selector naming and rotation are covered in DKIM Explained: Selectors and Key Rotation.
Alignment: the step that stops spoofing
DMARC only counts an SPF or DKIM pass if its domain aligns with the From domain. There are two modes, set separately for each check:
| Mode | Tag | Rule | From: example.com aligns with |
|---|---|---|---|
| Relaxed (default) | aspf=r, adkim=r | Same organizational domain | example.com, mail.example.com, eu.news.example.com |
| Strict | aspf=s, adkim=s | Exactly the same name | example.com only |
Relaxed alignment is right for almost everyone, because it lets you give each sending service its own subdomain. Strict alignment is occasionally used to stop a team that controls a subdomain from sending as the parent domain.
Alignment is what makes the attacker's job hard. They can publish SPF and DKIM for attacker.example and pass both checks, but neither result aligns with example.com in the From line, so DMARC fails and your policy applies.
DMARC: the policy and the reports
The DMARC record is a TXT record at _dmarc under the From domain:
$ dig +short TXT _dmarc.example.com
"v=DMARC1; p=reject; sp=reject; rua=mailto:dmarc-reports@example.com; adkim=r; aspf=r"
| Tag | Meaning |
|---|---|
| p | Requested disposition for failing mail: none (no DMARC enforcement), quarantine (request suspicious treatment) or reject (request rejection). Receivers may override these requests under local policy |
| sp | Policy for subdomains; if absent, subdomains inherit p |
| np | Policy for subdomains that do not exist at all, a favorite of spoofers; if absent, sp and then p apply |
| t | Test mode. With t=y, receivers treat failing mail one step softer than the policy: reject becomes quarantine and quarantine becomes none. The default is t=n |
| rua | Where participating receivers send daily aggregate reports. Not every receiver sends them, so a quiet report is not proof that no mail was sent |
| ruf | Where to send per-message failure reports; few large receivers send them, for privacy reasons |
| adkim, aspf | Alignment mode for DKIM and SPF, relaxed by default |
Older guides use a pct tag to apply the policy to a percentage of failing mail. RFC 9989 removed it, because receivers only applied 0 and 100 consistently, and replaced it with t. Receivers that follow the current standard ignore pct, so a record such as p=reject; pct=25 can mean rejecting all failing mail. Use t=y for a softer step instead. Receivers that have not moved to RFC 9989 yet ignore t, so during the transition pair it with pct=0, which those older receivers read the same way: p=quarantine; t=y; pct=0 is handled as none by both generations, and newer receivers ignore the pct tag. Remove any other pct value.
Aggregate reports, defined in RFC 9990, are XML summaries grouped by sending IP. Each row says how many messages that IP sent as your domain and whether SPF and DKIM passed and aligned. Most large mailbox providers send them, which makes them the best way to discover the services that send as you, from the CRM to the payroll system, before you start rejecting mail.
A safe path to p=reject
- Publish v=DMARC1; p=none; rua=mailto:… and confirm reports arrive. If the report address is in another domain, that domain must authorize it with a v=DMARC1 TXT record named after both domains, such as example.com._report._dmarc.reports.example.net for reports sent to an address at reports.example.net.
- Read two to four weeks of reports. List every source that sends as your domain and mark each as yours, a vendor's, or unknown.
- For each legitimate vendor, turn on DKIM signing with your domain and, where offered, a custom bounce domain so SPF aligns too. Retire anything nobody owns.
- Keep p=none for at least a month, then move to p=quarantine for at least another month and keep reading reports. Publishing it first as p=quarantine; t=y; pct=0 gives a gentler step that both old and new receivers honor.
- When the only failures left are spoofing and known forwarding, move to p=reject and set sp=reject.
Parked and defensive domains are popular for spoofing because nobody watches them. Give each one v=spf1 -all, a DMARC record with p=reject, and a null MX record (MX 0 .) so receivers know at once that no mail should come from it.
Mailing lists often change messages in ways that break DKIM, and they resend from their own servers, which breaks SPF. RFC 9989 says domains whose users post to mailing lists should not publish p=reject, because subscribers at other domains may stop receiving those posts or be unsubscribed. For a domain used by staff, p=quarantine is often the right end state. If you still choose reject, warn users first. Brand and transactional domains that people never use for list mail can go to reject safely.
Large mailbox providers now expect this work. Since February 2024, Google and Yahoo have required bulk senders to authenticate with SPF and DKIM and publish at least a p=none DMARC record, and mail from domains without them is increasingly filtered or refused.
What DMARC does not stop
DMARC can reduce exact-domain spoofing at receivers that enforce the requested policy. Receiver policy can override the requested disposition, and DMARC does not guarantee delivery or rejection. Phishing that avoids your domain needs other controls:
- Lookalike domains such as examp1e.com or a homograph built from other scripts, covered in Internationalized Domain Names. The attacker owns the domain and can pass DMARC for it.
- Display-name spoofing, where the name reads "Example IT Support" but the address is a free mailbox.
- Compromised accounts and vendors. Mail sent from a real, hijacked mailbox passes every check.
Once you are at enforcement, BIMI can display your logo next to authenticated mail, which gives readers a visible signal that is hard to fake. Protecting the mail in transit, so it cannot be read or redirected on the way to you, is a separate job covered in Secure Email Transport: STARTTLS and DANE.
How DNS Panopticon helps
The shared DNS scan reads a domain’s SPF and DMARC records; Domain Visualizer shows records and Security Posture displays findings for a missing SPF record, more than one SPF record, an SPF record that ends in +all, a missing DMARC record, and a policy left at p=none. It also looks for DKIM keys at the common selector1 and selector2 selectors. Your provider may use other selector names, so a missing result there is a prompt to check, not proof that DKIM is off.
Website Recon is useful from the other direction. When a suspicious message arrives, scan the domain in its From line to see when it was registered, by whom, and whether it looks like an impersonation of a domain you know.
To see how one message fared, paste its headers into Email Header Analyzer. It draws the route the message took, sets the envelope sender and DKIM signing domain beside the From address with their alignment, and shows the SPF, DKIM and DMARC results the receiving server recorded. The headers are parsed in your browser and never uploaded.
FAQ
If SPF and DKIM both pass, why can DMARC still fail?
Because DMARC also requires alignment. SPF can pass for a bulk mail provider's bounce domain and DKIM can pass for the provider's own signing domain, while the From address shows your domain. Neither result is about your domain, so DMARC fails until the provider signs with your domain or uses a custom bounce domain under it.
Do I need both SPF and DKIM for DMARC?
DMARC passes with either one aligned pass, but you should deploy both. SPF breaks when mail is forwarded, and DKIM breaks when a mailing list or gateway rewrites the message, so having both keeps legitimate mail passing in more situations.
Is p=none useless?
It requests no enforcement under DMARC; it does not guarantee delivery, because receivers still apply their own anti-abuse policies. It is a useful first step for monitoring. It turns on aggregate reports, which show the services sending as your domain from the receivers that report, so you can fix them before moving to quarantine and then reject.
Does DMARC stop all phishing?
No. It reduces exact-domain spoofing, where an attacker puts your own domain in the From address, at receivers that enforce the policy. It does not stop lookalike domains, display-name tricks, or mail sent from a real account that has been compromised. Those need user training, lookalike monitoring and account security.