TL;DRSPF lists the servers allowed to send email for your domain, DKIM signs each message so receivers can verify it wasn't forged or changed, and DMARC tells receivers what to do when a message fails both checks and where to send reports. You need all three: large mailbox providers require them from bulk senders, and missing records are the most common technical reason email lands in spam.
Why email authentication exists
The email protocol was designed without any way to prove who sent a message. Anyone can put any address in the From line. SPF, DKIM and DMARC are three DNS records added over the years to close that gap. Together they let a receiving server answer two questions: did this message really come from the domain it claims, and what should I do if it didn’t?
All three live in your domain’s DNS as TXT records, so you publish them at your DNS host or registrar, not in your email client.
| Record | Where it lives | What it proves | Fails when |
|---|---|---|---|
| SPF | yourdomain.com (TXT) | The sending server is allowed to send for the domain | The server’s IP isn’t listed, or the record is broken |
| DKIM | selector._domainkey.yourdomain.com (TXT) | The message was signed by the domain and not changed | The signature is missing, invalid, or the key can’t be found |
| DMARC | _dmarc.yourdomain.com (TXT) | SPF or DKIM passed for the domain in the From address | Neither SPF nor DKIM passes in alignment |
SPF: who may send for your domain
SPF (Sender Policy Framework) is a list of servers allowed to send email using your domain. The receiving server looks at the IP address that delivered the message, fetches your SPF record and checks whether that IP is on the list.
A typical record looks like this:
v=spf1 include:spf.protection.outlook.com include:sendgrid.net ip4:192.0.2.10 ~all
Read it left to right:
v=spf1marks it as an SPF record.include:spf.protection.outlook.comauthorises the servers Microsoft 365 uses.include:sendgrid.netauthorises a sending service.ip4:192.0.2.10authorises one specific server.~allsays anything else should softfail: treat it with suspicion.
The ending: ~all or -all?
| Ending | Name | Meaning | Use when |
|---|---|---|---|
-all | Fail | Mail from unlisted servers is not authorised | You are confident every sender is listed |
~all | Softfail | Mail from unlisted servers is suspicious | The safe default, especially with DMARC in place |
?all | Neutral | No opinion | Avoid: gives no protection |
+all | Pass | Anyone may send as you | Never |
The rules that break SPF most often
- One record only. A domain must publish exactly one SPF record. Two records cause a permanent error and SPF fails for everything. If two services each told you to “add an SPF record”, merge them into one.
- The 10-lookup limit. Every
include,a,mx,ptr,existsandredirectcosts a DNS lookup, and so does every such term inside each include. Past 10 in total, SPF returns a permanent error. Marketing, CRM and support tools each add includes, so this limit is easy to hit. The SPF checker counts the real number, including nested includes. - SPF checks the envelope, not the From line. SPF validates the return-path (bounce) domain. If a sending service uses its own return-path, SPF passes for their domain, not yours, which is why DMARC alignment matters.
- Forwarding breaks SPF. When a message is forwarded, it arrives from the forwarder’s IP, which isn’t in your record. DKIM survives forwarding; SPF usually doesn’t.
Fixing “too many DNS lookups”
- Remove includes for services you no longer use.
- Replace includes with
ip4:ranges for services that publish fixed IPs. - Move some senders to a subdomain (for example
news.yourdomain.com) with its own SPF record. - Avoid “flattening” services unless they update automatically: providers change their IPs, and a stale flattened record silently breaks.
Build a fresh record with the SPF generator.
DKIM: a signature on every message
DKIM (DomainKeys Identified Mail) adds a cryptographic signature to the headers of every message. Your mail server signs with a private key; the receiver fetches the matching public key from DNS and checks the signature. If anything in the signed parts of the message changed in transit, or the message wasn’t signed by your domain at all, DKIM fails.
The public key is published at a selector: a name that lets you have several keys, one per sending service.
selector1._domainkey.yourdomain.com TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqh..."
v=DKIM1marks it as a DKIM key.k=rsais the key type.ed25519also exists but RSA is far more common.p=is the public key itself. An emptyp=means the key has been revoked.
Selectors by provider
| Provider | Typical selector | How you enable it |
|---|---|---|
| Microsoft 365 | selector1, selector2 (CNAMEs to Microsoft) | Defender portal, Email authentication settings |
| Google Workspace | google by default | Admin console, Authenticate email |
| Zoho Mail | Chosen when you create the key | Mail admin, Domains, Email configuration |
| Sending services | Their own, such as s1, k1 or pm | The service’s domain-authentication setup |
To find the selector your mail actually uses, open a message you sent, view the original headers and look for s= in the DKIM-Signature header. Then check it with the DKIM checker.
DKIM best practice
- Use 2048-bit keys. 1024-bit keys are still accepted but weaker; anything shorter is rejected.
- Sign with your own domain. Many sending services sign with their domain by default. Set up “custom” or “branded” DKIM so the
d=domain in the signature matches your From domain. That is what makes DKIM count for DMARC. - Remove testing mode.
t=ytells receivers you’re still testing. Take it out when setup is done. - Rotate keys periodically, using a second selector so mail keeps verifying during the switch.
DMARC: the policy that ties it together
DMARC (Domain-based Message Authentication, Reporting and Conformance) does two things. It tells receivers what to do with mail that fails authentication for your domain, and it asks them to send you reports about everything they receive claiming to be from you.
v=DMARC1; p=quarantine; rua=mailto:dmarc@yourdomain.com
Alignment: the part people miss
DMARC doesn’t just check that SPF or DKIM passed. It checks that one of them passed for the same domain as the From address. That’s called alignment.
| Scenario | SPF | DKIM | DMARC |
|---|---|---|---|
| You send from Microsoft 365 with custom DKIM | Passes for your domain | Signed with your domain | Pass |
| A tool sends with its own return-path but signs with your domain | Passes for the tool’s domain (not aligned) | Signed with your domain | Pass (DKIM aligned) |
| A tool sends with its own return-path and its own DKIM domain | Not aligned | Not aligned | Fail |
| Someone spoofs your domain | Fails | Missing | Fail |
This is why setting up custom DKIM in every sending tool matters: it’s the most reliable way to pass DMARC.
The DMARC tags
| Tag | Meaning | Recommended |
|---|---|---|
p | Policy: none, quarantine or reject | Start at none, end at reject |
rua | Where aggregate reports go | Always set it |
sp | Policy for subdomains | Set if subdomains should differ |
pct | Share of failing mail the policy applies to | 100 once you’re confident |
adkim, aspf | Alignment mode: r relaxed or s strict | Relaxed (the default) for most setups |
ruf | Where forensic (per-message) reports go | Optional; few receivers send them |
p=none vs quarantine vs reject
p=nonedelivers failing mail as usual and only sends reports. It’s where everyone should start, and it satisfies the minimum that large providers require from bulk senders. But it doesn’t stop spoofing.p=quarantineasks receivers to send failing mail to spam.p=rejectasks receivers to refuse failing mail outright. This is full protection for your domain.
The safe path: publish p=none with a rua address, read the reports for two to four weeks, fix every legitimate sender that fails alignment, then move to quarantine, then reject. Create the record with the DMARC generator and verify it with the DMARC checker.
Reading DMARC reports
Aggregate reports arrive as XML files, usually daily, from each receiver. Each one lists source IPs that sent mail as your domain, how many messages, and whether SPF and DKIM passed and aligned. They’re how you find the CRM, invoicing tool or forgotten server that sends as you without being set up. A reporting service or a script that summarises them makes them far easier to read.
BIMI: your logo in the inbox
BIMI (Brand Indicators for Message Identification) lets some mailbox providers display your logo next to authenticated messages. It requires DMARC at quarantine or reject, a logo in a specific SVG format, and for most providers a verified mark certificate. It’s a reward for strong authentication rather than a deliverability fix on its own.
Do SPF, DKIM and DMARC affect deliverability?
Yes, in two ways. Directly, large providers now require all three from bulk senders, and mail that fails can be sent to spam or rejected; see bulk-sender requirements. Indirectly, authentication is what lets a provider attach reputation to your domain at all. Without it, every message starts from zero, and warm-up has nothing to build on.
Setup checklist
- List every service that sends email as your domain: mailbox provider, marketing, CRM, support desk, billing.
- Publish one SPF record that includes them all, and confirm it stays under 10 lookups.
- Enable DKIM in each service with your domain, 2048-bit where available.
- Publish DMARC at
p=nonewith aruaaddress. - Run the domain health check to confirm all three pass.
- Read reports for a few weeks, fix the senders that fail, then tighten to
quarantineandreject. - Recheck after every new tool or DNS change, or let deliverability monitoring do it daily.