How SPF, DKIM, and DMARC Actually Work
Try the interactive lab for this articleTake the quiz (6 questions · ~6 min)Email authentication is a patch over an old design choice. SMTP was built to move messages between cooperating hosts, not to prove that the visible author identity was genuine. A receiving server can see the TCP peer IP, the SMTP envelope, the message headers, and the body. None of those facts by themselves answer the question a mailbox provider really cares about: is this host allowed to send mail that claims to be from this domain, and if not, how aggressively should I treat it as abuse?
That is the job SPF, DKIM, and DMARC try to do together.
SPF authorises the sending path. DKIM signs the content. DMARC checks whether either authenticated identity lines up with the visible From: domain and lets the domain owner publish a policy for failures.
Those three sentences are accurate, but they leave out the part that confuses people in production: each protocol looks at a different identity layer, each one breaks in different ways, and a message does not need every check to pass in order to be accepted. Forwarding can break SPF while DKIM survives. A mailing list can break DKIM while still passing DMARC after rewriting the author field. A provider can reject on strong DMARC failure, or accept and quarantine later. Engineers who reduce the whole system to "email authentication passed" or "DMARC failed" usually end up debugging the wrong layer.
Use one realistic message as the anchor. A supplier in Athens sends an invoice to a buyer in Berlin. The visible author is [email protected]. The SMTP conversation might carry an envelope sender at [email protected]. The outbound service might be a cloud platform with IP 203.0.113.27. The message body might carry a DKIM signature with d=aegean-parts.eu and selector mta2026. The recipient mailbox provider has to decide whether those pieces fit together or whether someone is trying to impersonate the domain.
This article stays on the mechanism. We will look at which identity each protocol actually checks, how the DNS records are evaluated, why forwarding and mailing lists cause trouble, how DMARC alignment changes the decision, and how operators debug the result from headers and reports rather than guessing.
SPF, DKIM, and DMARC Solve Different Identity Problems
The first mistake is to treat SPF, DKIM, and DMARC as three versions of the same idea. They are not.
| Protocol | Main question | Identity it checks | Where policy lives | Common failure mode |
|---|---|---|---|---|
| SPF | Is this host allowed to send for this envelope domain? | MAIL FROM domain, or HELO domain in some fallback cases | DNS TXT on the sender domain | Forwarding breaks the source IP assumption |
| DKIM | Did a holder of this domain's private key sign these headers and this body? | d= signing domain and selected message content | DNS TXT under selector._domainkey | Intermediaries modify headers or body |
| DMARC | Does the visible From: domain align with a passing SPF or DKIM result, and what should receivers do if it does not? | Header From: domain plus SPF and DKIM results | DNS TXT at _dmarc.<domain> | Legitimate senders are not aligned or not fully inventoried |
That table is the shortest truthful summary, but the operational detail matters more than the slogan.
A receiving system sees several identities at once:
SMTP peer IP: 203.0.113.27
EHLO name: smtp-out.mailplatform.example
MAIL FROM: [email protected]
Header From: Aegean Parts <[email protected]>
DKIM d=: aegean-parts.eu
DKIM selector: mta2026Those are related claims, not one claim.
The peer IP says who connected.
The envelope sender says where delivery status notifications should go.
The visible From: header says who the message presents as the author to the human reader.
The DKIM d= value says which domain took cryptographic responsibility for the signed content.
DMARC exists because humans see the visible From: line, while SPF and DKIM often authenticate adjacent identities. Without alignment rules, a message could pass SPF for one domain and pass DKIM for another while still claiming to be from a third domain in the inbox view.
That is why mailbox providers do not stop at raw pass or fail flags. They ask a chain of more precise questions.
- Which domain authorised this sending IP, if any?
- Which domain signed the content, if any?
- Does either authenticated identity align with the visible
From:domain? - What policy did that visible domain publish for failures?
- Does the broader context, including reputation and content, support inbox placement?
Once you keep those five questions separate, the rest of the system becomes much easier to reason about.
SPF Authorises Sending Hosts For The Envelope Domain
SPF, standardised in RFC 7208, is a DNS-published allowlist for sending hosts. A domain owner publishes a TXT record that describes which IP ranges, hosts, or included policies may send mail using that domain in the SMTP envelope.
A simple SPF record looks like this:
aegean-parts.eu. 300 IN TXT "v=spf1 ip4:203.0.113.0/24 include:_spf.mailplatform.example -all"Read it literally.
v=spf1means this is an SPF policy.ip4:203.0.113.0/24authorises that IPv4 block directly.include:_spf.mailplatform.examplesays the receiver should also evaluate the referenced policy and treat a pass there as authorisation.-allsays everything else is unauthorised.
The check happens during or immediately after the SMTP transaction because the receiver already knows the peer IP and the envelope sender domain. The receiver extracts the domain from MAIL FROM, looks up its SPF TXT record, and evaluates the mechanisms against the connecting IP.
A simplified conversation might look like this:
220 mx.berlin-buyer.example ESMTP ready
EHLO smtp-out.mailplatform.example
MAIL FROM:<[email protected]>
RCPT TO:<[email protected]>The receiver now has two critical facts for SPF:
- connecting IP:
203.0.113.27 - domain under test:
mailer.aegean-parts.eu
If mailer.aegean-parts.eu publishes:
mailer.aegean-parts.eu. 300 IN TXT "v=spf1 include:_spf.mailplatform.example -all"and _spf.mailplatform.example ultimately authorises 203.0.113.27, SPF passes.
What SPF does not prove is just as important.
It does not prove that the human-visible From: line is honest.
It does not sign the message body.
It does not stop a compromised authorised platform from sending bad mail.
It does not survive any relay path that changes the sending IP without rewriting the envelope sender.
SPF is only a statement about whether this SMTP client is an authorised sender for this envelope domain.
That narrow scope is why SPF is still useful. The receiver gets an answer before it has to trust the message body. An obvious spoof from an unrelated network can fail quickly. Abuse desks can also reason about responsibility more cleanly. If a message came from an IP that the domain never authorised, the receiving side has a defensible signal before any content heuristics fire.
Real evaluation has more nuance than the simple example suggests.
SPF mechanisms can be:
- direct address matches such as
ip4andip6 - host lookups such as
aandmx - policy delegation through
include - explicit redirection through
redirect= - special cases such as
exists
Results are also richer than pass or fail.
passmeans an authorising mechanism matched.failmeans the policy explicitly says the host is not authorised.softfailusually comes from~alland signals suspicion rather than a hard block.neutralmeans the domain declined to make a strong statement.temperrormeans a temporary DNS or evaluation problem.permerrormeans the policy itself is malformed or exceeded evaluation limits.
A receiver may surface that result in an Authentication-Results header:
Authentication-Results: mx.berlin-buyer.example;
spf=pass smtp.mailfrom=mailer.aegean-parts.euThat line records what was checked, not what the mailbox provider ultimately did with the message.
SPF Breaks In Predictable Ways: Forwarding, Lookup Limits, And Shared SaaS Senders
SPF's design assumes the receiver can meaningfully judge the sending IP against the envelope sender domain. That assumption is reasonable for direct delivery from the original sender or their chosen outbound platform. It becomes fragile when the mail path changes.
Forwarding is the classic break.
Suppose a university in Madrid forwards a lecturer's mail to a hosted mailbox in Amsterdam. The original sender was [email protected], but the SMTP client that finally connects to Amsterdam is now the Madrid forwarder, not the original outbound platform. SPF still evaluates the original envelope sender domain unless the forwarder rewrites it. The forwarder IP is rarely listed in the original sender's SPF policy.
So the forwarded message often looks like this:
Connecting IP: 198.51.100.44 # forwarder in Madrid
MAIL FROM: [email protected]
SPF policy: only mailplatform.example is authorised
Result: spf=failNothing about that necessarily means forgery. It means SPF is path-bound. When the path changes, the authorisation no longer matches.
This is why the Sender Rewriting Scheme, or SRS, exists. A forwarder that cares about SPF compatibility can rewrite the envelope sender so that bounces return through the forwarder and SPF is now evaluated against the forwarder's own domain rather than the original sender's domain. The visible From: header can stay untouched while the transport identity changes.
Mailing lists, security gateways, and ticketing systems create similar path problems for SPF. Some receive and resend. Some preserve the original envelope sender too long. Some add a new envelope while keeping the visible author unchanged. The more intermediaries you have, the less SPF alone tells you about the human-visible identity.
DNS limits are the next common failure mode.
SPF evaluation is deliberately capped because an attacker could otherwise publish policies that trigger unbounded DNS recursion or huge evaluation costs. RFC 7208 limits SPF to ten DNS-mechanism lookups that count towards the budget. include, a, mx, exists, and redirect all consume from that budget in different ways.
A bloated enterprise policy can therefore turn into permerror even if the intent was innocent:
v=spf1 include:_spf.crm.example include:_spf.marketing.example include:_spf.support.example include:_spf.erp.example include:_spf.mailhost.example ~allIf those included records chain further includes, you can exceed the lookup cap quickly.
This matters because large organisations often accrete senders over time.
- Microsoft 365 for staff mail
- a payroll service for payslips
- a CRM for campaigns
- a support platform for ticket updates
- an invoicing vendor for payment reminders
- a regional subsidiary with its own mail relay
Every extra SaaS sender is a real operational dependency. If nobody maintains a current sender inventory, SPF becomes either too loose to be useful or too tangled to evaluate reliably.
The last failure mode is social rather than technical: teams publish SPF on the organisational domain while the actual envelope sender lives on a subdomain controlled by a vendor. The receiver checks the exact domain under MAIL FROM, not the domain a security team vaguely intended to protect. If the vendor uses bounce.mail.vendor.example and the organisation only publishes SPF on example.eu, the receiver will not infer the missing policy.
SPF is strongest when you treat the envelope domain as a real namespace with ownership, inventory, and change control. It is weakest when it is treated as background DNS trivia.
DKIM Signs The Message Content With A Domain-Published Key
DKIM, described in RFC 6376, solves a different problem. Instead of authorising the sending IP, it lets a domain sign selected message headers and the message body with a private key. The public key is published in DNS under a selector name. A receiver can then verify that the signed content survived transit and that the signer controlled the corresponding private key.
A typical header looks like this:
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=aegean-parts.eu; s=mta2026;
h=from:to:subject:date:message-id:mime-version:content-type;
bh=0F4nM3o4f8T5uL4A1xq3Jq2oN4sWb+1xR4o7V0Fz1jQ=;
b=H6zS2W...trimmed...And the DNS key record lives at:
mta2026._domainkey.aegean-parts.eu. 300 IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqh..."A few tags do most of the work.
d=is the signing domain.s=is the selector, which lets a domain publish multiple keys at once.h=lists the headers that were signed.bh=is the body hash after canonicalisation.b=is the actual signature over the canonicalised header set and metadata.c=declares canonicalisation rules for headers and body.
The basic DKIM flow is:
- The sender canonicalises selected headers and the body.
- The sender hashes the canonicalised body and places that value in
bh=. - The sender signs the relevant header block with its private key and places the result in
b=. - The receiver extracts selector and domain from
s=andd=. - The receiver fetches the public key from DNS.
- The receiver recomputes the body hash and verifies the signature.
If verification succeeds, the receiver learns two things.
First, the message content that was covered by the signature survived transit in the signed form.
Second, the signer controlled the private key for the d= domain at signing time.
That is not the same as saying the From: header is honest. A message could be signed by bulk-platform.example and still display From: [email protected]. DKIM authenticates the signer identity. DMARC later decides whether that signer identity is close enough to the visible author identity.
The canonicalisation setting is an important practical detail because email is messy. Intermediaries rewrap lines, normalise whitespace, or touch transfer encodings. relaxed/relaxed is common because it tolerates some harmless formatting changes better than simple/simple. Even so, DKIM is still content-sensitive. Change a signed header or the signed body in the wrong way and verification breaks.
You will often see the result recorded like this:
Authentication-Results: mx.berlin-buyer.example;
dkim=pass header.d=aegean-parts.eu header.s=mta2026Notice the wording. The receiver records the signing domain, not some abstract statement that the mail is globally trustworthy.
DKIM Survives Some Relays, But Not Careless Message Rewriting
DKIM is often described as more robust than SPF because it is not tied to the last-hop source IP. That is true, but it is only half the story.
DKIM can survive simple forwarding where the forwarder relays the message mostly unchanged. If the body bytes and the signed headers remain intact, the recipient can still validate the original signature even though the SMTP client IP changed completely. That is why forwarded mail often ends up with spf=fail and dkim=pass at the final destination.
This property makes DKIM the anchor that rescues many real-world mail flows.
But DKIM is not magical. It fails whenever an intermediary modifies signed material beyond what the chosen canonicalisation tolerates.
Common breakages include:
- a mailing list prepends
[List]to theSubject:header - a gateway appends a legal footer to the body
- a security product rewrites URLs for click tracking
- an archiving system normalises MIME structure
- a relay strips or reorders headers that were included in
h= - a broken sender signs a body before a later transformation step
Take a simple example. The sender signs this body:
Invoice attached.
Please pay within 14 days.A downstream mailing list appends:
Invoice attached.
Please pay within 14 days.
List footer: unsubscribe at https://lists.example/unsubThe stored body no longer matches the original body hash in bh=. The receiver can still read the message, but DKIM verification fails because the signed content changed.
Header mutations are just as important. If Subject: is in the signed header list and an intermediary changes Subject: June invoice to Subject: [Accounts] June invoice, the signature over the header block no longer verifies.
Operationally, this produces a subtle but important split.
- Some intermediaries are relays.
- Some intermediaries are resenders.
- Some are editors.
A pure relay can preserve upstream DKIM.
A resender may add its own DKIM signature, giving the message multiple signatures.
An editor often breaks the original signature and may or may not replace it with one aligned to its own domain.
That is why a single message can carry several DKIM-Signature headers. A marketing platform might sign. A downstream security gateway might sign again. A mailing list host might resign the modified copy. Receivers evaluate each signature separately.
This also explains why key management matters. Selectors exist so operators can rotate keys without breaking mail. You publish a new selector, sign new traffic with it, keep old selectors available while in-flight mail is still being verified, and retire the old record only after the safe overlap period. Delete the DNS key too early and valid recently sent mail starts failing verification downstream.
In incident response, DKIM answers a much narrower question than people think. It does not tell you whether a message is good. It tells you whether a domain that possessed the private key signed the message content that reached you, and whether that content still matches the signed form.
DMARC Aligns Authentication With The Visible From: Domain And Publishes Failure Policy
DMARC, standardised in RFC 7489, exists because people read the visible From: line, while SPF and DKIM frequently authenticate neighbouring identities instead.
A DMARC record lives at _dmarc.<domain> and might look like this:
_dmarc.aegean-parts.eu. 300 IN TXT "v=DMARC1; p=quarantine; rua=mailto:[email protected]; adkim=s; aspf=r; pct=100"Read the important parts literally.
p=quarantinetells receivers the requested policy for DMARC failure.rua=names an address for aggregate reports.adkim=srequests strict DKIM alignment.aspf=rrequests relaxed SPF alignment.pct=100says apply policy to all matching traffic.
DMARC evaluation starts from the visible author domain in the From: header. Suppose the message shows:
From: Aegean Parts <[email protected]>The receiver now asks two alignment questions.
- Did SPF pass for a domain aligned with
aegean-parts.eu? - Did DKIM pass for a signing domain aligned with
aegean-parts.eu?
If either answer is yes, DMARC passes.
That "either" matters. DMARC does not require both SPF and DKIM to pass. It requires at least one aligned authenticated path.
Alignment can be relaxed or strict.
With relaxed alignment, a subdomain can align with the organisational domain. For example:
- visible
From:domain:aegean-parts.eu - SPF authenticated domain:
mailer.aegean-parts.eu
That aligns under relaxed SPF alignment.
With strict alignment, the domains must match exactly.
- visible
From::aegean-parts.eu - DKIM
d=:mailer.aegean-parts.eu - result under
adkim=s: not aligned
A common production pattern is:
- SPF passes for a bounce domain on a subdomain
- DKIM passes for the organisational domain
- DMARC passes because the DKIM identity aligns cleanly with the visible author
Now look at a failure case.
A brand sends through a vendor that uses:
MAIL FROM: <[email protected]>
DKIM d=vendor-mail.example
From: [email protected]SPF may pass for vendor-mail.example.
DKIM may pass for vendor-mail.example.
DMARC still fails because neither passing identity aligns with aegean-parts.eu.
That is one of the most common onboarding mistakes with third-party senders. Security teams see green SPF and green DKIM checks in vendor documentation and assume DMARC will be fine. It will not unless at least one of those identities aligns with the visible author domain, often through a custom bounce domain, custom DKIM signing domain, or both.
DMARC policy values are also often misunderstood.
p=nonemeans monitor and report, not enforce rejection.p=quarantineasks receivers to treat failures suspiciously, often meaning spam or junk placement.p=rejectasks receivers to reject outright when possible.
The word "asks" is important. DMARC is a policy signal, not a law of physics. Large providers weigh local policy, reputation, ARC context, and abuse handling alongside it. A provider may still accept and folder a message that nominally failed DMARC. Another may reject at SMTP time. The protocol gives the domain owner leverage and reporting, not total control.
The result often appears like this:
Authentication-Results: mx.berlin-buyer.example;
spf=fail smtp.mailfrom=mailer.aegean-parts.eu;
dkim=pass header.d=aegean-parts.eu;
dmarc=pass header.from=aegean-parts.euThat header tells a very common story: forwarding broke SPF, DKIM survived, and DMARC passed on aligned DKIM.
Receivers Combine Authentication With Reputation, Content, And Local Policy
SPF, DKIM, and DMARC are not a complete anti-abuse system. They are identity and policy inputs into a larger decision engine.
A receiving provider typically evaluates mail in layers.
SMTP Edge
At connection time and during the envelope exchange, the receiver may already apply IP reputation, connection rate limits, malformed protocol checks, reverse DNS policy, and basic SPF awareness.
Content And Signature Analysis
After or during DATA, the receiver can verify DKIM, inspect MIME structure, scan attachments, check URL reputation, and calculate message fingerprints.
Author Policy And Alignment
The receiver then applies DMARC logic against the visible From: domain, with possible extra context from ARC if the message passed through a known forwarder or list environment.
Mailbox Placement
Even accepted mail still needs a destination decision: inbox, promotions, junk, quarantine, policy hold, or outright rejection before final acceptance.
This means several apparently contradictory statements can all be true.
- SPF failed.
- DKIM passed.
- DMARC passed.
- The provider still put the message in spam.
Or:
- SPF passed.
- DKIM passed.
- DMARC failed because neither result aligned.
- The receiver rejected at SMTP time because the domain published
p=reject.
Or:
- SPF, DKIM, and DMARC all passed.
- The mail was still rejected because the attachment carried malware.
Engineers get into trouble when they treat authentication as the whole decision. Large providers do not. Authentication tells them whether the claimed domain relationship is coherent. It does not tell them whether the sender is reputable, whether the campaign is wanted, whether the links are malicious, or whether the recipient has local filtering rules.
That broader context is why mailbox providers add their own trace headers. You may see something like:
Authentication-Results: mx.berlin-buyer.example;
spf=pass smtp.mailfrom=mailer.aegean-parts.eu;
dkim=pass header.d=aegean-parts.eu;
dmarc=pass header.from=aegean-parts.eu
ARC-Authentication-Results: i=1; mx.forwarder.example;
spf=pass smtp.mailfrom=mailer.aegean-parts.eu;
dkim=pass header.d=aegean-parts.eu;
dmarc=pass header.from=aegean-parts.eu
X-Spam-Score: 3.6
X-Spam-Reason: URL reputation lowARC, specified in RFC 8617, is worth mentioning here because forwarded mail often breaks direct downstream evaluation. ARC lets an intermediary preserve its view of upstream authentication results. Receivers still choose whether to trust that intermediary. ARC is context, not a blanket pardon. But it is often the difference between "this forwarder broke SPF and DKIM so I know nothing" and "this known forwarder says the original message authenticated cleanly before it modified the path".
The practical conclusion is simple: passing DMARC is necessary for strong impersonation protection on modern consumer mail, but it is not sufficient for inbox placement. Failing DMARC is serious, but it is not the only reason mail can be blocked. Production debugging needs the full decision trail.
Rolling SPF, DKIM, and DMARC Out Safely Requires Inventory And Change Control
The hardest part of DMARC programmes is rarely the syntax. It is discovering who is actually sending mail on behalf of the domain.
A clean rollout usually starts with sender inventory.
List every source that can put your domain in any of these places:
- visible
From:header - SMTP envelope sender
- DKIM signing domain
- bounce or return-path domain
That usually includes more systems than people expect.
- employee mail from Microsoft 365 or Google Workspace
- finance mail from an ERP or invoicing tool
- support notifications from a ticket system
- marketing campaigns from a bulk sender
- product mail from the application itself
- scanners, printers, monitoring appliances, and legacy systems
- subsidiaries and regional brands using shared infrastructure
If you skip this step and publish p=reject, you do not harden security. You create an outage with a security label attached to it.
A sensible sequence is:
- Publish correct SPF for each real envelope domain.
- Enable DKIM signing on every legitimate sender.
- Ensure at least one aligned identity path for every sender that uses the visible domain.
- Publish DMARC with
p=noneand collect aggregate reports. - Fix unauthorised or misaligned traffic revealed by the reports.
- Move to
p=quarantinewhen the real senders are under control. - Move to
p=rejectonly when the residual failures are understood.
Aggregate reports help here because they are less about individual messages and more about population-level truth. A report receiver gets XML summaries by source IP, domain, and authentication result. A trimmed example looks like this:
<record>
<row>
<source_ip>203.0.113.27</source_ip>
<count>4812</count>
<policy_evaluated>
<disposition>none</disposition>
<dkim>pass</dkim>
<spf>pass</spf>
</policy_evaluated>
</row>
<identifiers>
<header_from>aegean-parts.eu</header_from>
</identifiers>
<auth_results>
<spf>
<domain>mailer.aegean-parts.eu</domain>
<result>pass</result>
</spf>
<dkim>
<domain>aegean-parts.eu</domain>
<result>pass</result>
</dkim>
</auth_results>
</record>That tells you which infrastructure is really using your brand, at what volume, and with what authentication posture.
A few rollout rules save pain.
Keep SPF Small And Intentional
Do not treat SPF as a dumping ground. Remove retired senders. Flatten only with care, because operational convenience can create brittle static IP lists. Watch the ten-lookup limit.
Use Dedicated DKIM Selectors Per Platform Or Rotation Window
Per-platform selectors make incident handling cleaner. If one vendor is compromised or being migrated off, you can rotate or retire its selector without disturbing every other sender.
Align Third-Party Senders Deliberately
Many SaaS platforms support custom DKIM and custom return-path domains. Use them. A vendor signing only as vendor-mail.example is operationally convenient for the vendor, not for your DMARC alignment.
Be Careful With Subdomain Policy
DMARC can publish sp= for subdomains. That matters when staff mail lives on example.eu, marketing uses news.example.eu, and a subsidiary uses fr.example.eu. The organisational policy surface is often broader than one root record suggests.
Treat Reports As Signals, Not Gospel
Aggregate reports vary in volume, format quirks, and timing. Some providers report aggressively. Some are sparse. Use them for coverage and trend detection, not as a perfect ledger of every message.
A well-run rollout looks boring from the outside. That is good. Authentication changes should feel routine to users precisely because the team did the inventory work before the enforcement flag moved.
Debugging SPF, DKIM, and DMARC Failures Means Reading The Evidence In Order
When someone says, "our invoice mail is going missing", start by refusing the vague verb. Missing from where?
Did the outbound platform refuse to send?
Did the recipient MX reject at SMTP time?
Did the message get accepted and then junked?
Did a forwarder break authentication mid-path?
The shortest path to the answer is the trace, not intuition.
1. Inspect The Raw Headers
You want at least:
Authentication-Results- any
ARC-*headers Received:chainReturn-PathFrom:- all
DKIM-Signatureheaders
Those show which domains were actually in play.
2. Compare Identities Explicitly
Write them down side by side.
Return-Path domain: mailer.aegean-parts.eu
From domain: aegean-parts.eu
DKIM d=: aegean-parts.eu
Source IP: 203.0.113.27Now ask:
- Did SPF evaluate the return-path domain you expected?
- Did DKIM sign with the domain you expected?
- Did one of those identities align with the visible author domain?
3. Query DNS Directly
Use DNS from a shell, not screenshots from an admin panel.
dig TXT mailer.aegean-parts.eu
dig TXT mta2026._domainkey.aegean-parts.eu
dig TXT _dmarc.aegean-parts.euFor DKIM, make sure the selector record actually exists and contains the expected public key. For SPF, check whether the record under test is the one you thought the sender was using. For DMARC, confirm the policy and alignment settings.
4. Validate The Scenario, Not Only The Record
A correct SPF record on the wrong domain is still operationally wrong.
A valid DKIM key in DNS does not help if the sender never used that selector.
A p=reject record does not tell you which legitimate sender forgot to align.
The message trace must match the DNS state.
5. Look For The Known Pattern Classes
If SPF fails but DKIM and DMARC pass, suspect forwarding or a path change.
If DKIM fails after a mailing list, suspect body or subject modification.
If SPF and DKIM pass but DMARC fails, suspect misalignment on a third-party sender.
If everything fails only for one SaaS platform, suspect stale DNS or a platform that was never onboarded correctly.
6. Use Provider And MTA Tools Where They Help
On your own systems, inspect queue logs and outbound signing status.
On managed platforms, use whatever header analysis or deliverability consoles they expose, but verify their claims against raw headers and DNS.
For isolated tests, operators often use tools such as swaks, opendkim-testkey, or vendor-specific header analysers. The exact tool matters less than the discipline: reproduce, inspect, and compare what the protocol says to what the control plane claims.
7. Keep A Mental Model For Mixed Outcomes
The most common production traces are mixed, not pure.
Authentication-Results: mx.berlin-buyer.example;
spf=fail smtp.mailfrom=mailer.aegean-parts.eu;
dkim=pass header.d=aegean-parts.eu;
dmarc=pass header.from=aegean-parts.euThat is not contradictory. It usually means the path changed but the content signature survived.
Or this:
Authentication-Results: mx.berlin-buyer.example;
spf=pass smtp.mailfrom=bounce.vendor-mail.example;
dkim=pass header.d=vendor-mail.example;
dmarc=fail header.from=aegean-parts.euThat is not mysterious either. It means the vendor authenticated itself successfully but did not authenticate as the visible brand domain.
Careful operators do not memorise one green path. They learn these mixed patterns and read them quickly.
Mailing Lists, Aliases, And Gateways Turn Clean Theory Into Messy Production
The hardest messages to explain are often not obvious spoofs. They are legitimate messages that passed through one or more intermediaries that changed just enough state to confuse downstream receivers.
Mailing lists are the classic example. A list host may receive a message from aegean-parts.eu, add a subject prefix, append a footer, and resend it to thousands of subscribers from its own infrastructure. From the subscriber's mailbox provider, that new copy is no longer a simple relay of the original message.
Several things may now be true at once.
- the original SPF identity is no longer relevant because the list host is the new SMTP client
- the original DKIM signature may be broken because the subject or body changed
- the visible
From:line may still show the original author domain - the list host may add its own DKIM signature for the list domain
That combination is exactly why mailing list software sometimes rewrites the visible author field into forms such as From: Aegean Parts via Ops List <[email protected]>. It looks ugly, but it gives DMARC a chance to align with the list domain after the message was materially altered by the list.
Aliases and helpdesk systems create a milder version of the same problem. A support address in Paris might expand one public mailbox into an internal queue, a CRM connector, and an archival system. One path may preserve the original body, another may add ticket metadata, and a third may forward to an external SaaS platform. By the time the message reaches the final mailbox, the path and content assumptions behind SPF and DKIM may no longer match the first hop.
This is where ARC becomes practically useful. An intermediary that saw the message earlier in the route can attach an Authenticated Received Chain that says, in effect, "when this message arrived here, SPF, DKIM, and DMARC looked like this." A downstream receiver still has to decide whether that intermediary is trustworthy. ARC does not override local policy. But for known forwarders and list operators it preserves evidence that would otherwise be lost once the path or body changed.
The operational lesson is that not every DMARC failure means the original sender misconfigured DNS, and not every SPF failure means forgery. Sometimes the message entered a workflow that legitimately reshaped it. Good receivers try to distinguish that from abuse by combining direct checks, ARC context, sender reputation, and local knowledge of common forwarders or list hosts.
Good senders do their part too.
- transactional mail that must survive forwarding should almost always carry aligned DKIM
- list operators should understand when their modifications break upstream signatures
- helpdesk and gateway products should document whether they relay, resend, or edit mail
- security teams should test real forwarding and list flows before turning DMARC straight to reject
The theory of SPF, DKIM, and DMARC is clean. Real mail routes are not. The protocols still hold up, but only if you remember which component was proving path, which was proving content, and which was judging visible authorship after the intermediaries had their turn.
SPF, DKIM, and DMARC Work Best When You Treat Them As One System With Separate Failure Boundaries
SPF, DKIM, and DMARC are often sold as a checklist.
Publish a TXT record.
Turn on signing.
Move the policy to reject.
That framing misses why they matter.
SPF is valuable because it ties envelope domains to allowed sending infrastructure.
DKIM is valuable because it gives a verifiable signature over message content and a signer domain that can survive simple forwarding.
DMARC is valuable because it pulls those adjacent signals back to the identity humans actually see in the inbox and gives domain owners a way to ask receivers for consistent handling.
Their real strength appears when you respect the boundaries between them.
- If the path changes, expect SPF trouble.
- If the content changes, expect DKIM trouble.
- If the authenticated identity does not match the visible author, expect DMARC trouble.
That is not fragility so much as honesty. Each protocol fails where its underlying assumption stops being true.
The engineering task is therefore not to demand perfect green ticks in every imaginable mail path. It is to design real sender flows so that at least one aligned authentication path survives the legitimate transformations your mail is expected to encounter, while unauthorised impersonation becomes easy for receivers to identify and suppress.
If you keep one sentence in your head, make it this one: SPF checks who was allowed to hand over the message, DKIM checks who signed the bytes that arrived, and DMARC checks whether either of those facts supports the name the recipient actually sees.