---
title: "SPF, DKIM and DMARC explained: how inboxes trust mail"
description: "What SPF, DKIM and DMARC each check, why alignment decides whether DMARC passes, and a safe order for moving a domain from p=none to p=reject."
url: "https://nextmail.sh/blog/spf-dkim-dmarc-explained"
---

[Blog](https://nextmail.sh/blog.md)[Deliverability](https://nextmail.sh/blog/tags/deliverability.md)

# SPF, DKIM and DMARC explained: how inboxes trust mail

What SPF, DKIM and DMARC each check, why alignment decides whether DMARC passes, and a safe order for moving a domain from p=none to p=reject.

Benjamin Nextmail team

October 31, 2026 5 min read

TL;DR

- SPF lists the servers allowed to send for your domain, and receivers check it against the hidden return address, not the From line people see.
- DKIM signs every message, so a receiver can prove which domain sent it and that nobody changed it on the way.
- DMARC passes only when SPF or DKIM passes for the same domain as the visible From address, and it tells receivers what to do with mail that fails.

Email was designed for a smaller, more trusting network. The protocol that moves mail between servers lets a sender write any address in the From line, and nothing in the message itself proves that address is real. That is how a forged invoice can arrive looking like it came from your own domain.

Receivers close that gap with three checks, each published as a DNS record on the sending domain: SPF, DKIM and DMARC. Gmail and Yahoo have required all three from bulk senders since February 2024, and mail from a domain without them is more likely to land in spam or be refused.

## What each record checks

| Record | Published at | What it proves |
| --- | --- | --- |
| SPF | `example.com` | The server that handed over the message may send for the domain in its return address |
| DKIM | `s1._domainkey.example.com` | The signing domain sent the message, and nobody changed it on the way |
| DMARC | `_dmarc.example.com` | SPF or DKIM passed for the domain in the visible From line, and what to do when neither did |

Each one answers a different question, and none of them alone stops a forged From line. The sections below take them one at a time.

## SPF: who may send for your domain

SPF is a TXT record on your domain that lists the servers allowed to send its mail. A record for a company that sends through one service looks like this:

txt

```
example.com.  TXT  "v=spf1 include:_spf.example.net ~all"
```

`include:` pulls in the servers your email service publishes, and the `all` at the end says what to make of everyone else. `~all` asks receivers to treat other servers as suspicious, and `-all` asks them to fail the check.

The catch is which address SPF looks at. It checks the envelope sender, the return address servers use for bounces (also called the Return-Path), not the From line people see in their inbox. A forger can pass SPF for a domain they own while showing yours in From, so SPF on its own does not stop the forged invoice. DMARC does, further down.

### The ten-lookup limit

Every `include`, `a`, `mx`, `ptr`, `exists` and `redirect` in your record costs the receiver a DNS lookup, and the standard caps a single check at ten. A record that needs more fails with a permanent error, which most receivers treat as having no SPF at all. It is easy to cross once your marketing, billing and support tools each add their own include, so count again whenever you add a sender.

SPF also breaks when mail is forwarded, because the forwarding server is not on your list. That is one reason DMARC never relies on SPF alone.

Every mechanism, both lookup limits and the fixes for forwarding are in our guide [What is SPF?](https://nextmail.sh/blog/what-is-spf.md)

## DKIM: a signature that travels with the message

DKIM signs each message with a private key held by the sending service and adds the signature in a `DKIM-Signature` header. Two tags in that header matter here: `d=` names the signing domain, and `s=` names the selector, which tells the receiver where to look up the public key.

txt

```
s1._domainkey.example.com.  TXT  "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..."
```

The receiver fetches that key, checks the signature and learns two things: the domain in `d=` really signed the message, and the signed headers and body were not changed in transit. Because the signature travels inside the message, DKIM usually survives forwarding, which SPF does not.

Use 2048-bit keys, which the current standard recommends over the older 1024-bit minimum. Give every service that sends for you its own selector, so you can rotate or revoke one key without touching the others.

The signature itself, tag by tag, is in our guide [What is DKIM?](https://nextmail.sh/blog/what-is-dkim.md)

## DMARC: the policy that ties them together

DMARC adds the rule the other two are missing. A message passes DMARC only when SPF or DKIM passes **and** the domain it passed for matches the domain in the visible From line. That match is called alignment. It is relaxed by default, so `mail.example.com` aligns with `example.com`, and a strict setting asks for the exact same name.

The record lives at `_dmarc` on your domain:

txt

```
_dmarc.example.com.  TXT  "v=DMARC1; p=none; rua=mailto:dmarc-reports@example.com"
```

`p=` is the policy for mail that fails:

- `none` changes nothing about delivery and only asks for reports.
- `quarantine` asks receivers to treat failing mail as spam.
- `reject` asks them to refuse it outright.

`rua=` is where receivers send aggregate reports, usually one XML file a day from each large mailbox provider. Each report lists the servers that sent as your domain and whether their mail passed. Those reports are how you find the forgotten newsletter tool or the office printer that still sends as you, before a strict policy starts throwing their mail away.

> A forged message can pass SPF and DKIM for the forger's own domain. Only DMARC asks whether those passes belong to the domain in From.

Alignment, the reports and every tag of the record are in our guide [What is DMARC?](https://nextmail.sh/blog/what-is-dmarc.md)

## A safe order for turning it on

Moving straight to `p=reject` is the classic way to lose real mail. This order avoids it:

1. List every service that sends as your domain: your mailbox provider, your email API, and your newsletter, billing and help desk tools.
2. Publish SPF with each of them included, and turn on DKIM signing in every one.
3. Publish DMARC at `p=none` with an `rua` address, and read the reports for two to four weeks.
4. Fix every legitimate sender that fails, usually by adding its include or turning on its signing.
5. Move to `p=quarantine`, watch the reports for a few more weeks, then move to `p=reject`.

A domain that never sends mail is the exception. Publish `v=spf1 -all` and a DMARC record at `p=reject` straight away, so nobody can send in its name.

## Where Nextmail fits

When you add a domain to Nextmail, the domain page lists every record to publish and checks each one against what public DNS answers, with the usual reason when a record does not match. If the domain has no DMARC record of its own, you get a starter record at `p=none` with a reporting address already filled in, to copy into your DNS or write with a sync. Moving the policy to `quarantine` or `reject` stays your decision, made on the domain's DMARC tab.

To look at a domain you already run, the [deliverability checker](https://nextmail.sh/tools/deliverability.md) reads its SPF, DKIM, DMARC, BIMI and MX records from live DNS, and the [DMARC record generator](https://nextmail.sh/tools/dmarc.md) builds the next record in the rollout. The steps for adding a domain are in [Connect a domain](https://nextmail.sh/docs/get-started/domain.md), and the starter record is described in [DMARC policy](https://nextmail.sh/docs/knowledge/addresses/dmarc.md).

## Free tools

Try what you just read on your own setup. They are free and need no account.

[Email deliverability checker SPF, DKIM, DMARC, BIMI and MX, read live.](https://nextmail.sh/tools/deliverability.md)[DMARC record generator Build the next DMARC record, step by step.](https://nextmail.sh/tools/dmarc.md)

- [Deliverability](https://nextmail.sh/blog/tags/deliverability.md)
- [DNS](https://nextmail.sh/blog/tags/dns.md)
- [Email authentication](https://nextmail.sh/blog/tags/email-authentication.md)

## References

1. 1 [RFC 7208: Sender Policy Framework (SPF) for Authorizing Use of Domains in Email, Version 1](https://www.rfc-editor.org/rfc/rfc7208) IETF
2. 2 [RFC 6376: DomainKeys Identified Mail (DKIM) Signatures](https://www.rfc-editor.org/rfc/rfc6376) IETF
3. 3 [RFC 8301: Cryptographic Algorithm and Key Usage Update to DomainKeys Identified Mail (DKIM)](https://www.rfc-editor.org/rfc/rfc8301) IETF
4. 4 [RFC 9989: Domain-Based Message Authentication, Reporting, and Conformance (DMARC)](https://www.rfc-editor.org/rfc/rfc9989) IETF
5. 5 [Email sender guidelines](https://support.google.com/a/answer/81126) Google
6. 6 [Sender best practices](https://senders.yahooinc.com/best-practices/) Yahoo

Keep reading

## Related articles

Oct 31, 2026 9 min read

### What is SPF? How SPF records work and where they break

SPF is the DNS record that lists the servers allowed to send mail for your domain. How receivers check it, what each part means and what quietly breaks it.

Arta Deliverability

Oct 31, 2026 9 min read

### What is DKIM? How DKIM signatures and records work

DKIM is a signature on every email that proves which domain vouches for it and that nothing changed on the way. How it works, tag by tag, and which keys to use.

Benjamin Deliverability

Oct 31, 2026 9 min read

### What is DMARC? Policy, reports and getting to p=reject

DMARC is a DNS record that checks SPF and DKIM against your visible From domain, tells inboxes what to do with mail that fails and reports who sends as you.

Arta Deliverability

Try it yourself

## Your email, on your own domain.

Nextmail puts your domains, sending and inbox in one place, with the full API on every plan, the free one included.

[Open mail](https://nextmail.sh/mail/inbox) [Get Started](https://nextmail.sh/signup.md)[All articles](https://nextmail.sh/blog.md)
