The short version
SPF answers "is this server allowed to send mail for this domain?" DKIM answers "was this message signed by the domain, and has it changed since?" DMARC ties the two to the address the reader actually sees in the From line and tells the receiver what to do when neither check passes for that address. All three are plain TXT records in your DNS. None of them needs software on your side beyond what your mail provider already runs.
| Record | Lives at | Checks | Standard |
|---|---|---|---|
| SPF | example.com | The IP address of the sending server against a list you publish | RFC 7208 (2014) |
| DKIM | selector._domainkey.example.com | A cryptographic signature in the message header against a public key you publish | RFC 6376 (2011) |
| DMARC | _dmarc.example.com | That SPF or DKIM passed for the domain in the visible From address, and what to do if not | RFC 7489 (2015), replaced by RFC 9989 (2026) |
SPF: which servers may send
An SPF record is a TXT record on your domain that starts with v=spf1 and lists the servers allowed to send mail for it. RFC 7208 says SPF records must be published as TXT records; a separate SPF record type existed during the experimental phase and has been discontinued. The receiving server takes the IP address that connected to it and walks the list from left to right until something matches.
Read it as: the server at 192.0.2.10 may send, so may every server listed in the SPF record of _spf.mailhost.example.net (your mail provider would give you the real name), and everything else fails. Each mechanism can carry a qualifier in front. RFC 7208 defines four: + pass (the default when nothing is written), - fail, ~ softfail, a weak statement that the sender is probably not authorized, and ? neutral, which receivers must treat like no record at all. The all mechanism always matches, so it goes last and sets the answer for every server not listed before it.
What SPF actually checks
SPF does not look at the From address in your mail program. It checks the envelope sender, the address the sending server gives in the SMTP MAIL FROM command, and RFC 7208 recommends also checking the HELO name the server introduces itself with. A newsletter service often uses its own domain in MAIL FROM so bounces come back to it. SPF then passes, but for the service's domain, not yours. That gap is what DMARC closes.
The 10 lookup limit
Each time a receiver evaluates your record, some terms make it ask DNS again. RFC 7208, section 4.6.4, caps the total at 10 during one evaluation. Go over and the result is permerror, which means your SPF counts as broken, not as passing. RFC 7208 also asks receivers to allow no more than two lookups that return nothing, the so-called void lookups.
| Term | Counts | Why |
|---|---|---|
| include | Yes | Each include, plus every counted term inside the record it pulls in |
| a | Yes | One lookup for the A or AAAA records of the name |
| mx | Yes | One lookup, and each mail server it returns needs an address lookup (at most 10) |
| ptr | Yes | RFC 7208 says do not use it |
| exists | Yes | One lookup |
| redirect= | Yes | Hands the whole check to another record |
| ip4, ip6 | No | The address is written in the record, nothing to look up |
| all | No | Always matches; put it last |
The trap is the include. Your record may show only four includes, one for your office mail, one for a newsletter tool, one for your shop and one for a help desk. But if each of those records contains two includes of its own, the receiver has already made 12 lookups and your record fails everywhere. Count recursively. Ways back under 10: remove services you no longer use, replace includes with the ip4 and ip6 ranges a service publishes when it allows that, and send bulk mail from a subdomain such as news.example.com with its own SPF record.
One record only
RFC 7208 does not permit more than one SPF record for the same name, and a receiver that finds two returns permerror. When a new service tells you to "add an SPF record", merge its include into the one you have. The DNS lookup reads your SPF record, flags a second one, checks how it ends and counts the lookups at the top level of the record. The lookups inside each include you still have to add yourself.
Where SPF breaks
SPF checks the last server that handed over the message. When someone forwards your mail and keeps your address in MAIL FROM, the forwarding server is not in your list, and RFC 7208 says the check will fail unless the forwarder rewrites MAIL FROM to its own domain. That is the main reason SPF alone is not enough.
DKIM: a signature on every message
With DKIM, your mail server signs each outgoing message with a private key and adds a DKIM-Signature header. The receiver fetches the matching public key from your DNS and checks the signature. If the signed headers or the body changed on the way, the check fails. RFC 6376 describes the purpose as letting the owner of the signing domain claim some responsibility for a message.
The key lives at a name built from a selector you or your provider choose, then _domainkey, then your domain. Selectors let you run several keys at once, one per service, and replace a key without a gap.
The value after p= is the public key in base64, the same text you get from the RFC's Appendix C commands without the BEGIN and END lines. A 2048-bit key is too long for one DNS string, since a string holds at most 255 characters (RFC 1035), so it is published as two strings that receivers join without spaces, as RFC 6376 requires. An empty p= means the key has been revoked, and t=y marks a key in testing mode, where receivers should treat signed mail like unsigned mail.
What the signature header says
The header that travels with each message names the signing domain in d= and the selector in s=, so the receiver knows to look up s1._domainkey.example.com. h= lists the signed headers, and RFC 6376 requires the From header to be among them. bh= is the hash of the body and b= the signature itself. RFC 6376 recommends rsa-sha256 for a=.
Key length
RFC 6376 requires at least 1024-bit RSA keys for long-lived keys. Google's sender guidelines ask for at least 1024 bits and recommend 2048. If your provider still gives you a 1024-bit key, ask whether it offers 2048.
DKIM survives forwarding better than SPF, because the signature travels inside the message rather than depending on which server delivers it. RFC 6376 notes that relays typically leave the content alone and preserve the signature, while mailing lists that add a footer can break it.
DMARC: the rule that ties them together
SPF and DKIM can both pass for a domain that is not yours, as the newsletter example showed. DMARC adds one condition, called alignment: the domain that passed must match the domain in the From header, the one your reader sees. A message passes DMARC when at least one of the two checks passes and is aligned. In the default relaxed mode, a subdomain counts as aligned with its parent, so mail.example.com aligns with example.com. Strict mode, aspf=s or adkim=s, demands an exact match.
That is the monitoring record from RFC 9989's examples. v=DMARC1 must come first. p= is your request to receivers for mail that fails: none means only report, quarantine means treat it as suspicious, usually the spam folder, and reject means refuse it. rua= is where aggregate reports go; without it receivers send none. These reports are how you find every service that sends mail as you, including the ones nobody told you about.
| Tag | Meaning | Default |
|---|---|---|
| p | Policy for the domain: none, quarantine or reject | none, if the record is otherwise valid (RFC 9989) |
| sp | Policy for subdomains that exist | Same as p |
| np | Policy for subdomains that do not exist (new in RFC 9989) | Same as sp, else p |
| rua | Addresses for aggregate reports | No reports |
| ruf | Addresses for failure reports on single messages | No reports |
| adkim, aspf | Alignment mode for DKIM and SPF: r relaxed, s strict | r |
| t | Test mode: y asks receivers to apply one level less than the policy (new in RFC 9989) | n |
The standard changed in 2026
DMARC was first published in 2015 as RFC 7489, an informational document. In May 2026 it was replaced by RFC 9989, now on the Standards Track. The new version removes the pct, rf and ri tags, adds np, psd and t, and finds the organizational domain by walking up the DNS tree instead of using the public suffix list. Receivers ignore tags they do not know, so an older record with pct=100 keeps working, but new records should use t=y for a trial run instead of a percentage.
From none to reject
Do not jump straight to reject. Any legitimate service you forgot, such as an invoicing tool or a form plugin on your website, will have its mail refused. RFC 9989, section 7.4, describes the path: publish p=none for at least a month and read the reports, then p=quarantine for a similar period, then reject. It also says domains whose users post to mailing lists should not publish p=reject, because lists often change messages in ways that break both checks.
One message, three checks
Say your shop sends order confirmations through a mail service. The From line reads orders@example.com. The service uses bounces.mailservice.example.net as the envelope sender and signs with DKIM.
- SPF: the receiver checks the connecting IP against the SPF record of bounces.mailservice.example.net. It passes, but for mailservice.example.net, which does not align with example.com.
- DKIM, default setup: the service signs with d=mailservice.example.net. The signature is valid, but again not aligned.
- DMARC: neither passing check is aligned with example.com, so DMARC fails and your p= policy applies.
The fix is in the service's settings, if it supports signing with your own domain. You publish the key they give you at their selector, for example s1._domainkey.example.com, the signature then carries d=example.com, DKIM passes aligned, and DMARC passes even though SPF still is not aligned. One aligned pass is enough. Some services also let you set a custom bounce domain, such as bounces.example.com, which makes SPF align as well.
What Gmail and Yahoo require
Both providers turned these records from good practice into conditions in February 2024. Google's rules apply to mail sent to personal Gmail accounts; Yahoo's to Yahoo Mail.
| Requirement | Gmail, all senders | Gmail, bulk senders | Yahoo, bulk senders |
|---|---|---|---|
| SPF and DKIM | SPF or DKIM | Both | Both |
| DMARC | Not required | Required, p=none is enough | Required, at least p=none, must pass |
| From aligned with SPF or DKIM | No | Yes | Yes |
| Valid forward and reverse DNS for the sending IP | Yes | Yes | Yes (all senders) |
| One-click unsubscribe for marketing mail | No | Yes | Yes, honored within 2 days |
| Spam rate | Below 0.30%, aim for 0.10% | Below 0.30%, aim for 0.10% | Below 0.3% |
Google counts you as a bulk sender once you send close to 5,000 messages or more to personal Gmail accounts within 24 hours, adding up all subdomains of the same primary domain, and you stay one permanently after reaching that once. Senders with an existing unsubscribe link had until June 1, 2024 to add one-click unsubscribe, and Google's FAQ says it is ramping up enforcement from November 2025, with temporary and permanent rejections for mail that does not comply. Yahoo does not publish a volume number for its bulk sender rules. Google also requires TLS for sending and DKIM keys of at least 1024 bits.
Setting up all three, in order
- List every service that sends mail as your domain: your mailbox provider, newsletter tool, shop, invoicing, help desk, website forms. Check the nameservers first with the WHOIS lookup or DNS lookup, so you edit the zone that is actually live.
- Build one SPF record with each service's include or IP range, count the lookups, and end it with ~all.
- Turn on DKIM in every service and publish each key at the selector it names. Prefer 2048-bit keys.
- Publish DMARC with p=none and a rua address, then read the reports for a few weeks.
- Fix what fails, mostly services that sign with their own domain, then move SPF to -all and DMARC to quarantine and, if no mailing list issue stands in the way, to reject.
- Check the live records with the DNS lookup after each change. DNS answers are cached for the TTL, so a change can take up to that long to show everywhere.
Authentication gets your mail judged on its merits; it does not make readers want it. If you send newsletters, the email subject line checker flags subject lines that look like spam before they ever reach a filter.
Frequently asked questions
Do I need all three records?
If you send more than a few thousand messages a day to Gmail or Yahoo, yes. Since February 2024 both require bulk senders to have SPF and DKIM and to publish a DMARC record with at least p=none, with the visible From domain aligned with SPF or DKIM. For smaller senders, Gmail asks for SPF or DKIM at a minimum, but setting up all three costs nothing and is the only way to stop others from sending mail in your name.
Should my SPF record end with ~all or -all?
In RFC 7208, the qualifier "-" means fail, a clear statement that any server not listed is not authorized, and "~" means softfail, a weaker statement that it is probably not authorized. Start with ~all while you are still finding every service that sends for you, then switch to -all once your DMARC reports show nothing legitimate failing. Never use +all: it authorizes every server on the internet.
Can I have two SPF records?
No. RFC 7208 does not permit multiple SPF records for the same name, and a receiver that finds more than one returns permerror, which means your SPF does not work at all. When a new service asks you to "add an SPF record", add its include to the one record you already have instead.
Why does the DNS lookup tool not show my DKIM record?
A DKIM key lives at a name made of a selector and _domainkey, for example s1._domainkey.example.com, and the selector is chosen by whoever signs your mail. There is no standard way to list all selectors of a domain. Look up the s= value from the DKIM-Signature header of a message you sent, then query that name for a TXT record.
Is p=none enough?
For Gmail and Yahoo bulk sender rules, yes: both ask for a DMARC policy of at least p=none. But p=none only asks receivers to report, not to act, so it does not stop someone from sending mail that pretends to be you. Use it to collect reports, fix every legitimate source, then move to quarantine. The current DMARC standard, RFC 9989, suggests at least a month at p=none and a similar period at quarantine before reject.
Sources
- RFC 7208, Sender Policy Framework (SPF), April 2014: TXT record format, qualifiers and results, one record per name, the limit of 10 DNS-querying terms (section 4.6.4), the ptr mechanism, forwarding (section 10.3)
- RFC 6376, DomainKeys Identified Mail (DKIM) Signatures, September 2011: signature tags, key records under _domainkey, 1024-bit minimum for long-lived keys, From must be signed, Appendix C key generation
- RFC 7489, Domain-based Message Authentication, Reporting, and Conformance (DMARC), March 2015: record location, tags, identifier alignment
- RFC 9989, DMARC, May 2026: Standards Track version that obsoletes RFC 7489, new np, psd and t tags, removal of pct, rf and ri, mailing list guidance (section 7.4), example records (Appendix B)
- RFC 1035, Domain Names: Implementation and Specification, section 3.3: a character-string is one length octet followed by up to 255 characters
- Google Workspace Admin Help: Email sender guidelines (requirements for all senders and for senders of 5,000 or more messages a day, starting February 1, 2024)
- Google Workspace Admin Help: Email sender guidelines FAQ (bulk sender definition, June 1, 2024 one-click unsubscribe deadline, enforcement ramp-up from November 2025)
- Yahoo Sender Hub: Sender best practices (requirements for all senders and bulk senders, enforcement beginning February 2024)