If you send cold email from your own domain, three DNS records decide whether mailbox providers believe the mail really comes from you: SPF, DKIM and DMARC. Get them wrong and good messages land in spam or get rejected. Get them right and you've cleared the first bar every major provider now sets.
This guide explains each record in plain English, shows example records for example.com, and walks through a safe DMARC rollout. For the wider picture, including unsubscribe rules and complaint rates, see our email deliverability guide.
The short version
| Record | Question it answers | Where it lives | Standard |
|---|---|---|---|
| SPF | Is this server allowed to send mail for this domain? | TXT record at example.com | RFC 7208 |
| DKIM | Did this domain sign the message, and is it unchanged? | TXT record at selector._domainkey.example.com | RFC 6376 |
| DMARC | Does SPF or DKIM pass for the From domain, and what if not? | TXT record at _dmarc.example.com | RFC 9989 |
SPF: who is allowed to send
SPF (Sender Policy Framework) is a published list of the servers and services allowed to send mail for your domain. When a message arrives, the receiving server compares the connecting IP address with the SPF record of the envelope sender's domain. That's the MAIL FROM address in the SMTP conversation, also called the return path, which is not always the address people see.
A domain that sends through a hosted mailbox provider plus one outreach tool might publish something like this (the include values are placeholders; your providers give you the real ones):
| Host | Type | Value |
|---|---|---|
| example.com | TXT | v=spf1 include:_spf.mailhost.example include:spf.outreachtool.example ~all |
- v=spf1 marks the record as SPF.
- include: pulls in the list of servers a provider publishes for its customers.
- ~all (softfail) says mail from anywhere else is probably not authorized. -all (fail) says it definitely isn't. Many teams start with ~all and tighten once they're sure the record is complete.
Common SPF mistakes
- Two SPF records. RFC 7208 says a domain must not publish more than one, and treats multiple records as a permanent error. Merge them into one.
- Too many lookups. RFC 7208 caps an SPF check at 10 DNS lookups, and every include counts, along with any includes nested inside it. Go over and the check fails with a permanent error.
- A forgotten sender. Every service that sends as your domain, including your CRM, help desk and outreach tool, has to be covered.
SPF has two weak spots. It checks the envelope sender, not the visible From address. And it often breaks when mail is forwarded, because the forwarding server's IP isn't in your record. DKIM covers both gaps.
DKIM: a signature on every message
DKIM (DomainKeys Identified Mail) adds a cryptographic signature to each outgoing message. Your sending service signs with a private key, and you publish the matching public key in DNS. The receiver fetches the key and checks the signature, which proves two things: the domain named in the signature's d= tag signed the message, and the signed parts weren't changed in transit.
| Host | Type | Value |
|---|---|---|
| s1._domainkey.example.com | TXT | v=DKIM1; k=rsa; p=MIIBIjANBgkqh... (public key, shortened) |
Here "s1" is the selector. Selectors let you run several keys at once, one per sending service, and rotate keys without downtime. Each signed message carries a DKIM-Signature header naming both, for example d=example.com; s=s1.
- Use a strong key. Google requires a DKIM key of 1024 bits or longer for mail to personal Gmail accounts and recommends 2048 bits where your provider supports it.
- Sign with your own domain. Many sending tools sign with their own domain by default. That passes DKIM but not DMARC alignment, so set up custom DKIM for example.com in each tool.
- DKIM usually survives forwarding, because the signature travels inside the message. That's why it matters even when SPF is in place.
DMARC: alignment plus a policy
DMARC connects SPF and DKIM to the From address people actually see. A message passes DMARC when at least one of these is true:
- SPF passes and the envelope sender's domain aligns with the From domain.
- DKIM passes and the signing domain (d=) aligns with the From domain.
That match is called alignment. With relaxed alignment, the default, subdomains of the same organizational domain count as a match, so bounce.example.com aligns with example.com. Strict alignment (adkim=s or aspf=s) requires the exact same domain.
| From address | Envelope sender domain | DKIM d= | DMARC (relaxed) |
|---|---|---|---|
| [email protected] | bounce.example.com | example.com | Pass: both aligned |
| [email protected] | bounces.outreachtool.example | example.com | Pass: DKIM aligned |
| [email protected] | bounces.outreachtool.example | outreachtool.example | Fail: nothing aligned |
The DMARC record also states a policy for mail that fails, and where to send reports:
| Host | Type | Value |
|---|---|---|
| _dmarc.example.com | TXT | v=DMARC1; p=none; rua=mailto:[email protected] |
- p= is the policy: none (monitor only), quarantine (treat as suspicious, usually the spam folder) or reject (refuse the message).
- rua= is where receivers send aggregate reports: summaries of which IP addresses sent mail as your domain and whether they passed.
- sp= optionally sets a different policy for subdomains.
Rolling out DMARC: none, then quarantine, then reject
Jumping straight to p=reject is how teams end up blocking their own invoices and calendar invites. Ramp up in stages instead.
- 1Start at p=none with reports on. Delivery doesn't change. Read the aggregate reports and list every service that sends as your domain.
- 2Fix every legitimate source. Add missing services to SPF, turn on custom DKIM signing, and keep checking the reports until your real mail passes with alignment.
- 3Move to p=quarantine. Failing mail now goes to spam. For a softer step, publish quarantine with t=y first, which asks receivers to treat it as none while you watch the reports.
- 4Move to p=reject. Once the only failures left are sources you don't recognize, reject them. This is the strongest protection against people spoofing your domain.
There's no fixed timetable. Move to the next stage when the reports are clean, not when a date arrives.
What Google and Yahoo require
Since February 2024, Gmail and Yahoo have enforced sender requirements that make authentication mandatory. Here's the authentication-related core of both:
| Requirement | Who it applies to |
|---|---|
| SPF or DKIM | All senders |
| Valid forward and reverse DNS for sending IPs | All senders |
| Spam rate below 0.3% | All senders |
| Both SPF and DKIM | Bulk senders |
| A DMARC record (p=none is enough) | Bulk senders |
| From domain aligned with SPF or DKIM | Bulk senders |
| One-click unsubscribe for marketing and subscribed messages | Bulk senders |
Google puts the bulk tier at more than 5,000 messages a day to Gmail accounts, and recommends keeping the spam rate in Postmaster Tools under 0.1%. Yahoo asks bulk senders to honor unsubscribes within 2 days. These rules change, so check Google's sender guidelines and Yahoo's best practices before a large send.
Most cold email teams don't send 5,000 a day to Gmail from one domain. Meeting the bulk-sender rules anyway costs little and keeps you covered as you grow.
Why authentication won't save a bad list
SPF, DKIM and DMARC prove the mail comes from you. They say nothing about whether the recipient exists. Send to dead addresses and the receiving servers return hard bounces to a perfectly authenticated domain.
Authentication actually makes your track record easier to follow, because providers can tie every bounce and complaint to your domain. Yahoo's best practices ask senders to remove invalid recipients promptly. A rising bounce rate is a list problem, not a DNS problem.
So the order is simple: authenticate your domain once, then verify every list before it goes out. Our email verification best practices and bounce rate guide cover the list side.
Setup checklist
- Publish one SPF record that covers every service sending as your domain, within 10 lookups.
- Turn on custom DKIM signing with your own domain in each sending service, 2048-bit where supported.
- Publish a DMARC record at p=none with a rua address, and read the reports.
- Confirm your From domain aligns with SPF or DKIM for every mail stream.
- Step DMARC up to quarantine, then reject, once the reports are clean.
- Verify every list before sending, and remove hard bounces right away.



