InboxAudit

SPF, DKIM and DMARC: how email authentication actually works

Three DNS records decide whether your mail reaches an inbox. They are usually explained separately, which is why so many domains end up with all three published and still failing. They are one system, and the piece that ties them together — alignment — is the piece almost every guide skips.

SPF says which servers may send

SPF is a TXT record on your domain listing the servers allowed to send mail as you. A receiver takes the IP that connected, checks it against your list, and gets back pass, fail, softfail, neutral, permerror or temperror.

The catch is cost. Evaluating SPF is capped at ten DNS lookups, and that cap is recursive: every include: costs one lookup plus whatever its own record chains to. Exceed ten and receivers return permerror, which means SPF stops working entirely — not partially, entirely. Nothing in your DNS looks broken when this happens, which is why it goes unnoticed for years.

SPF also breaks whenever a message is forwarded, because the forwarding server becomes the connecting IP. That is not a misconfiguration; it is inherent to the design. It is the main reason DKIM exists.

DKIM proves the message was not altered

DKIM signs outgoing mail with a private key. The matching public key sits in DNS at selector._domainkey.yourdomain. A receiver fetches the key, verifies the signature, and learns two things: which domain took responsibility for the message, and whether the signed parts changed in transit.

Because the signature travels with the message, DKIM survives forwarding. It does not survive modification — a mailing list that appends a footer invalidates the body hash, which is the single most common cause of "body hash did not verify".

Selectors cannot be listed from DNS. You can only check the ones you know about, which is why a checker reporting "no DKIM found" is evidence, not proof.

DMARC ties them to the address the reader sees

Here is the part that trips people up. SPF authenticates the envelope sender — the hidden bounce address. DKIM authenticates whichever domain signed. Neither is necessarily the From: address the recipient actually reads, and forging that visible address is the entire point of a phishing email.

DMARC closes the gap by requiring alignment: at least one of SPF or DKIM must pass for a domain that matches the From: domain. One aligned pass is enough. Both can pass and DMARC can still fail, if neither aligns.

This is why "SPF passes but DMARC fails" is such a common and confusing report. SPF genuinely passed — for your sending platform's bounce domain, not for yours.

The order to fix things in

  1. Publish SPF with every sending source, and check the lookup count. Under ten with headroom to spare.
  2. Enable DKIM on every platform that sends as you. This matters more than SPF, because it survives forwarding.
  3. Publish DMARC at p=none with a rua address. Change nothing else yet.
  4. Read the reports for a few weeks. They will name senders you forgot about. Every deployment finds at least one.
  5. Move to p=quarantine, then p=reject once reports are clean.
Skipping step 4 is what turns a DMARC rollout into an outage. The reports exist precisely because nobody has a complete list of who sends mail as their domain.

Check your domain