Guides

How to set up SPF, DKIM and DMARC for your own email

Three acronyms, three DNS records, and without them more and more of your email lands in the spam folder or never reaches the recipient at all. This guide explains what each of the three standards actually checks, what the records look like and in which order to introduce them so nothing breaks along the way.

The three standards in three sentences each

SPF answers the question of which servers may send email for your domain. You publish a list in DNS, and the receiving server compares it with the IP address the message came from. If it does not match, that counts against the message.

DKIM adds a cryptographic signature to every single message. The public key is published in DNS, and the receiving server verifies the signature against it. If the signature checks out, the message was not altered in transit and comes from someone who holds the private key.

DMARC is the policy for when SPF and DKIM do not line up. You decide whether the receiving server should deliver the message anyway, put it in the spam folder or reject it. On top of that, you get reports on who is sending email in your name.

The order is no accident: DMARC only works once SPF and DKIM are in place.

To see where your domain stands right now, use the SPF, DKIM and DMARC checker. It reads the records, counts the DNS lookups in your SPF record and tells you what is missing. This guide explains what to do with the results.

SPF: who may send for your domain

An SPF record is a TXT record on the domain itself. A typical one looks like this:

v=spf1 include:spf.spamgo.de include:spf.protection.outlook.com -all

The record, field by field

  • v=spf1 is the version tag and must come first.
  • include: pulls in another provider's list of servers. This is the usual approach: instead of listing individual IP addresses, you point to the provider, who maintains the list. If they change servers, your record does not break.
  • ip4: and ip6: list individual addresses or networks. You need these when a device or server with a static IP sends directly.
  • -all at the end means: nothing else is allowed. The softer ~all only means "suspicious". Start with ~all and switch later.

Note the singular: a domain may have exactly one SPF record. Two records is an error that many checking tools do not flag clearly enough, and the result is an SPF setup that some receiving servers simply treat as invalid. When you add another provider, add an include: to the existing record.

The ten-lookup limit

Every include: triggers a DNS lookup on the receiving side, and the list behind it can contain more includes. The standard allows ten of these lookups in total. Go over that and you do not get an "almost passed", you get a permanent error, and the check fails as if there were no SPF record at all.

In practice, this hits companies that have added a mail provider, a newsletter tool, a CRM, a ticketing system and accounting software over the years. The fix: remove entries nobody needs anymore, and add services that only send from a static IP directly as ip4: instead of through include:.

DKIM: the signature that survives the trip

SPF has a weakness: it checks the sending IP address. When a message is forwarded, that address changes and SPF fails, even though the message is genuine. DKIM does not have this problem, because the signature lives in the message itself and forwarding does not touch it.

When sending, the mail server signs certain headers and the body with a private key. The matching public key is published as a TXT record in DNS, under a name like mb1._domainkey.yourcompany.com.

Selector, key length, rotation

The part before ._domainkey is called the selector. It exists so that several senders can sign side by side: your mail provider uses one selector, your newsletter tool another, and they do not get in each other's way. If you send through several servers, you need a DKIM record for each of them. Create all of them, or only some of your messages will carry a valid signature.

As for key length: 2048 bits is standard today, and 1024 bits is considered outdated. Some DNS providers do not accept TXT values that long in one piece; the value then has to be split into several strings, which most control panels do automatically.

Rotating keys now and then is a good idea, but nothing to lose sleep over. The usual process: create a new selector, publish it in DNS, switch sending over to it, leave the old record in place for a few more days, then delete it.

DMARC: the policy when something does not match

DMARC is a TXT record at _dmarc.yourcompany.com:

v=DMARC1; p=none; rua=mailto:dmarc@yourcompany.com

The key part is p=, the policy. And there is a detail that often gets overlooked: DMARC does not just check whether SPF or DKIM pass, but whether the domain they checked matches the visible From address. This is called alignment. A message can pass SPF and still fail DMARC if the technical sender belongs to a different domain than the one shown in the inbox.

none, quarantine, reject in the right order

  • p=none: nothing happens, you only receive reports. The right place to start, but not a place to stay forever.
  • p=quarantine: messages that fail go to the spam folder.
  • p=reject: they are rejected.

The path always leads from none through quarantine to reject, with several weeks in between. If you jump straight to reject, you will discover the senders you forgot when customers start calling.

Test mode with t=y instead of pct=

It used to be common to use pct=25 as an intermediate step: the policy was supposed to apply to only a quarter of the messages. That tag no longer exists. RFC 9989 removed pct from the standard because in practice almost nobody used values other than 0 and 100. A receiver that follows the current standard ignores the tag and applies p= to all messages. So if you still publish pct=25, you get the full effect instead of a quarter.

It has been replaced by t=y. With it, you publish the policy but ask receivers not to apply it yet and to stay one level below: for now, p=reject is treated as quarantine, and p=quarantine as none. Reports keep coming in as before. Once they are clean, remove t=y and the policy takes effect.

v=DMARC1; p=reject; t=y; rua=mailto:dmarc@yourcompany.com

Subdomains: sp= and np=

Unless you say otherwise, your policy also applies to all subdomains. With sp= you set a separate policy for existing subdomains, and with np= for subdomains that do not exist in DNS at all. The second case is the more interesting one: those are exactly the names a spoofer makes up, because they are free to pick any. np=reject closes that gap, even while p= is still set to none. np also comes from RFC 9989.

Reading reports without making it a full-time job

The address in rua= receives XML reports from the large mailbox providers every day. They are barely readable by hand. Set up a separate mailbox for them and use a reporting service, or only go through them in the first few weeks, when the point is to track down unknown senders. That is exactly what the p=none phase is for.

Rollout order without breaking delivery

  1. List every sender: mail provider, newsletter tool, CRM, online store, ticketing system, printers, accounting. This list is usually longer than you think.
  2. Update SPF, starting with ~all. Watch the ten-lookup limit.
  3. Set up DKIM for every sender that supports it. Create all selectors in DNS.
  4. Publish DMARC with p=none and collect reports for two to four weeks.
  5. Sort out any unexpected senders: either add them to SPF and DKIM or shut them down.
  6. Move to p=quarantine (with t=y first if you want to be careful), watch for a few more weeks, then move to p=reject and switch SPF to -all.

Depending on the provider, DNS changes can take up to 24 hours to become visible everywhere. So do not plan several steps for the same day.

Common mistakes

  • Two SPF records. The most common mistake of all, usually because someone added a second provider without updating the existing record.
  • DMARC without DKIM. Technically valid, but it does not survive forwarding. A message sent to a mailing list will then fail on a regular basis.
  • The record in the wrong place. DKIM and DMARC belong on subdomains (selector._domainkey and _dmarc), SPF on the domain itself. Some DNS control panels append the domain name automatically and others do not, and then the record ends up under a doubled name where nobody will ever look it up.
  • Never checking again after setup. Records disappear when you switch providers, or a colleague overwrites them. Checking them regularly is part of the job.

How MailBridge takes this off your plate

In the portal, you add your sender domain and see the record found and the record expected side by side for SPF, DKIM and DMARC, with copy buttons for host, type and value. The suggested SPF record extends your existing one instead of replacing it. If your DMARC policy is still at p=none, the portal suggests moving on. All domains are checked daily; if a record breaks later, it shows up as an action item on the dashboard.

How to use it is covered in the guide to domains and DNS. If you used to send through Microsoft 365 and it no longer accepts your messages, see the article on SMTP relay for Microsoft 365.

Sources and technical background

Once you have created the records, double-check them: the SPF, DKIM and DMARC checker shows you right away whether they come out the way you meant them.

DNS is not your favorite topic? Try MailBridge free for 14 days, and the portal shows you the finished records ready to copy. If you like, we can go over them together: start@mailbridge.email