SPF, DKIM and DMARC: what developers get wrong
Password reset emails land in spam, or a stranger sends mail that looks like it came from your domain. Both are DNS problems, and both come down to three records.
SPF: who may send
An SPF record is a TXT record on the domain that lists the servers allowed to send for it, for example v=spf1 include:_spf.example.net ip4:203.0.113.10 -all. Two rules trip people up:
- One record only. A domain must publish a single SPF record. Two of them is a permanent error, and receivers may treat both as failing. When you add a new sending service, merge it into the existing record.
- Ten DNS lookups at most. Each
include,a,mxand similar mechanism costs lookups, including the ones nested inside the included records. Going over ten produces a permanent error. Adding three marketing tools quickly gets you there. Trim unused providers, or use a flattening service, and check the count with an SPF validator.
-all says other senders should fail, ~all marks them as soft fail. Move to -all once you are confident about the list.
DKIM: the message is signed
Your mail provider signs each message with a private key, and receivers verify the signature using the public key in DNS, published at selector._domainkey.example.com. Points to check: each service that sends mail for you needs its own selector and record. Keys of at least 2048 bits are recommended. Rotate the keys occasionally, and remove selectors of services you no longer use.

DMARC: what to do with failures
DMARC ties the two together and tells receivers what to do. It is published as a TXT record at _dmarc.example.com:
v=DMARC1; p=none; rua=mailto:[email protected]
The important idea is alignment: it is not enough that SPF or DKIM passed for any domain. One of them must pass for a domain that matches the visible From address. A message sent through a third party with the third party's return-path can pass SPF and still fail DMARC.
The p value moves through none (monitor only), quarantine and reject. The usual rollout is to start with p=none and a rua address, read the aggregate reports for a few weeks to find every legitimate source, fix those, and then tighten. Many domains stay on p=none forever, which gives visibility and no protection.
Practical checks
dig +short TXT example.com
dig +short TXT _dmarc.example.com
dig +short TXT selector1._domainkey.example.com
Send a test message to a mailbox that shows the original headers and look for spf=pass, dkim=pass and dmarc=pass in the Authentication-Results header.
Use a subdomain for bulk and marketing mail (news.example.com), so its reputation problems do not hit your transactional messages, and publish a restrictive record for domains that never send mail (v=spf1 -all).
Why forwarded mail breaks SPF but often keeps DKIM
A message forwarded through an intermediate mail server, a corporate forwarding rule, a mailing list, arrives at its final destination from the forwarder's IP address, not from any server your SPF record lists, so SPF fails for genuinely legitimate mail through no fault of the original sender. DKIM tends to survive forwarding better, because the signature covers the message headers and body rather than depending on which server the connection came from; as long as the forwarder does not modify the signed parts of the message (some mailing lists that rewrite the subject line or add a footer do break the signature by changing signed content), DKIM can still pass even when SPF cannot. This is part of why DMARC alignment only requires one of the two to pass, not both, and why relying on SPF alone would make ordinary mail forwarding look like a spoofing attempt.
A newer, related standard, ARC (Authenticated Received Chain), exists specifically to let a trusted forwarder (a mailing list, a corporate gateway) attest to what it saw when it received a message, so the final recipient can weigh that attestation even after the forwarder's own changes would otherwise have broken DKIM. Supporting it as a sender is optional and mostly relevant if you run a service that forwards or relays mail on behalf of others.