TL;DR: Automated email senders fail deliverability not because of content, but because of broken authentication. SPF, DKIM, and DMARC work as a layered system — each solves a different problem. Get all three right, or your agent's mail lands in spam regardless of how clean the content is.

SPF, DKIM, and DMARC for automated email senders aren't optional configuration — they're the foundation that determines whether your agent's mail reaches an inbox or disappears into spam. Human senders can recover from authentication failures by asking recipients to check their spam folder. Automated senders have no fallback. If authentication breaks, mail fails silently and the agent never knows.
This guide covers the mechanics of each protocol, how they interact, and where automated senders most commonly break the chain.
What SPF actually does (and doesn't do)
SPF (Sender Policy Framework) authorizes IP addresses to send mail for a domain. The receiving MTA does a DNS TXT lookup on the envelope sender's domain and checks whether the connecting IP is listed. If it isn't, the check fails.
SPF lives in DNS as a TXT record on your sending domain:
v=spf1 ip4:203.0.113.10 include:_spf.youresp.com -all
ip4:203.0.113.10— explicitly authorize a single IPinclude:_spf.youresp.com— delegate to a third party's SPF record (e.g., your ESP)-all— hard fail anything not listed (use~allfor soft fail during testing)
The critical distinction: SPF validates the envelope sender (the MAIL FROM address in the SMTP handshake), not the From: header the recipient sees. This matters enormously for automated senders that use separate bounce addresses.
SPF lookup limits
RFC 7208 caps DNS lookups during SPF evaluation at 10. Each include:, a:, mx:, and redirect= mechanism that triggers a DNS lookup counts toward this limit. Large ESPs often chain several include: directives together, and you can unknowingly exceed 10 lookups before you've added your own IP.
Check your current count:
dig TXT yourdomain.com | grep spf
Exceeding 10 lookups causes a permerror, which many receivers treat as a hard SPF failure. For automated senders operating across multiple sending services, SPF flattening — resolving all include: chains into explicit ip4: ranges — is often necessary.
How DKIM works at the protocol level
DKIM (DomainKeys Identified Mail) solves a different problem than SPF. Where SPF validates the sending IP, DKIM validates that message content hasn't been tampered with in transit, using a cryptographic signature.
Your sending server signs outbound messages with an RSA (or Ed25519) private key. The signature is added as a DKIM-Signature header:
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=yourdomain.com; s=mail2026;
h=from:to:subject:date:message-id:content-type;
bh=47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=;
b=<base64-encoded-signature>
Key fields:
d=— the signing domain (must match or align with yourFrom:domain for DMARC)s=— the selector, which identifies which public key to look up in DNSh=— the list of headers included in the signaturebh=— hash of the message bodyb=— the actual signature
The public key lives at {selector}._domainkey.{domain} as a TXT record:
mail2026._domainkey.yourdomain.com TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkq..."
Canonicalization matters for automated senders
DKIM has two canonicalization modes for headers and body: simple and relaxed. The c=relaxed/relaxed setting is almost always correct for automated senders. simple canonicalization breaks if any MTA in transit modifies whitespace — which mailing list software, spam filters, and some SMTP relays do routinely.
If your DKIM signatures are failing despite correct key configuration, canonicalization mismatch is the first thing to check.
What headers to include in the signature
At minimum, sign: from, to, subject, date, message-id, content-type, and mime-version. For automated senders using custom reply-to addresses for routing, also include reply-to — unsigned headers can be injected by an attacker.
Don't include received headers. They're added by every hop and will always break the signature.
DKIM key rotation
Rotate DKIM keys at least annually, and immediately if a private key is exposed. The rotation process:
- Generate a new keypair
- Publish the new public key under a new selector (e.g.,
mail2026b._domainkey.yourdomain.com) - Wait for DNS TTL to propagate (typically 300–3600 seconds)
- Switch your sending infrastructure to sign with the new key
- Retire the old selector after a few days (old mail in transit may still need verification)
For Ed25519 keys (supported in DNS as k=ed25519), the keys are shorter and signature computation is faster, but receiver support is still patchy. Use RSA-2048 as the primary and Ed25519 as a secondary if you want both.
DMARC: the policy layer
DMARC (Domain-based Message Authentication, Reporting & Conformance) doesn't authenticate messages itself. It reads the results of SPF and DKIM checks and applies a policy when both fail. It also enforces alignment — the requirement that authenticated domains match the visible From: domain.
A DMARC record lives at _dmarc.yourdomain.com:
_dmarc.yourdomain.com TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@yourdomain.com; ruf=mailto:dmarc-failures@yourdomain.com; pct=100; adkim=r; aspf=r"
p=— policy:none(monitor only),quarantine(route to spam),reject(drop the message)rua=— aggregate report destination (daily XML digests of authentication results)ruf=— forensic report destination (individual failure reports; many receivers don't send these)pct=— percentage of mail the policy applies to (use 100 in production)adkim=— DKIM alignment:r(relaxed, organizational domain match) ors(strict, exact domain match)aspf=— SPF alignment: same options
Alignment is where automated senders break
DMARC passes if at least one of SPF or DKIM passes with alignment. Alignment means the authenticated domain matches the From: header domain.
SPF alignment: the MAIL FROM domain must match the From: domain (relaxed: organizational domain match; strict: exact match).
DKIM alignment: the d= value in the DKIM signature must match the From: domain.
Automated senders routinely break DMARC alignment in two ways:
Bounce address mismatch: the envelope sender (
MAIL FROM) is set to a bounce processing address on a different domain, likebounce+hash@mailprovider.com. This fails SPF alignment because theFrom:domain isyourdomain.combut the envelope sender domain ismailprovider.com. Fix: use DKIM alignment instead — configure the signing domain to match yourFrom:domain.Subdomain sending: sending from
agent@mail.yourdomain.comwith SPF records only onyourdomain.com. Relaxed alignment covers this (organizational domain match), but strict alignment (aspf=s) will reject it. Know your alignment mode.
┌──────────────────────────────────────────────────────────┐
│ DMARC Evaluation │
│ │
│ SPF Pass + SPF Alignment → DMARC PASS │
│ OR │
│ DKIM Pass + DKIM Alignment → DMARC PASS │
│ │
│ Both fail alignment → Apply p= policy │
└──────────────────────────────────────────────────────────┘
How the three protocols interact
sequenceDiagram
participant Agent as Agent Sender
participant MTA as Your MTA
participant Receiver as Receiving MTA
Agent->>MTA: Submit message
MTA->>MTA: Sign with DKIM private key
MTA->>Receiver: SMTP delivery
Receiver->>Receiver: SPF check on MAIL FROM IP
Receiver->>Receiver: DKIM verify via DNS lookup
Receiver->>Receiver: DMARC alignment check
Receiver->>Receiver: Apply policy or deliver
Each check is independent. SPF failing doesn't prevent DKIM from passing. DMARC then decides what to do with the combination of results. For automated senders, DKIM alignment is the most reliable path because it depends on your signing configuration, not on the envelope sender domain matching anything.
Specific failure modes for automated senders
1. Shared IP reputation contamination
When your agent sends from a shared IP pool, other tenants' sending behavior affects your SPF-verified IP's reputation. A burst of spam from another tenant on the same IP degrades inbox placement for every sender on that IP. This is why dedicated IPs matter at volume — you control the IP's reputation history entirely.
2. Forwarding breaks SPF
When a recipient forwards mail, the forwarding server's IP isn't in your SPF record. SPF fails. DKIM survives forwarding as long as the message body isn't modified. This is another reason to prioritize DKIM alignment over SPF alignment in your DMARC configuration.
3. DKIM signature on modified messages
If your sending pipeline modifies message content after signing — adding tracking pixels, rewriting links, appending footers — the DKIM body hash (bh=) will no longer match and the signature fails. Sign after all modifications are complete.
4. Missing DMARC record
No DMARC record means receivers have no policy to apply. Some treat this as implicit p=none; others apply stricter heuristics. Either way, you get no aggregate reports and no visibility into authentication failures across the ecosystem. Publish a DMARC record at p=none with rua= set before you send a single message, then tighten the policy after reviewing reports.
5. Subdomain coverage
DMARC policy inheritance: if _dmarc.yourdomain.com has p=reject but _dmarc.mail.yourdomain.com has no record, receivers fall back to the organizational domain's policy. That's usually correct, but if you want a different policy per subdomain, publish an explicit record. The sp= tag controls subdomain policy directly:
_dmarc.yourdomain.com TXT "v=DMARC1; p=reject; sp=quarantine; rua=mailto:dmarc@yourdomain.com"
Deployment checklist for automated senders
| Step | Action | Verify With |
|---|---|---|
| SPF | Publish TXT record, stay under 10 lookups | dig TXT yourdomain.com, mxtoolbox SPF check |
| DKIM | Generate RSA-2048 keypair, publish public key, configure signing | DKIM validator, email header inspection |
| DMARC | Publish p=none + rua= first, tighten after 2 weeks |
DMARC analyzer, aggregate reports |
| Alignment | Confirm DKIM d= matches From: domain |
Check Authentication-Results header on delivered mail |
| IP reputation | Warm dedicated IPs before high volume | Google Postmaster Tools, MX reputation tools |
| Reporting | Parse aggregate rua reports weekly |
DMARC report parsers (parsedmarc, dmarcian) |
Reading authentication results headers
Every delivered message includes an Authentication-Results header added by the receiving MTA. Read it to debug failures:
Authentication-Results: mx.google.com;
dkim=pass header.i=@yourdomain.com header.s=mail2026 header.b=AbCdEfGh;
spf=pass (google.com: domain of bounce@mail.yourdomain.com designates 203.0.113.10 as permitted sender)
smtp.mailfrom=bounce@mail.yourdomain.com;
dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=yourdomain.com
dmarc=pass with p=QUARANTINE means the policy would have quarantined this mail if DMARC had failed — but it passed because DKIM aligned. dis=NONE means no disposition action was taken.
If you see dmarc=fail, the dis= value tells you what the receiver actually did: NONE, QUARANTINE, or REJECT.
Platforms like Mails.ai expose sender reputation signals and authentication status per message, cutting out the manual header inspection step when debugging agent sending pipelines at scale.
BIMI: the next layer
BIMI (Brand Indicators for Message Identification) builds on DMARC. If your domain has p=quarantine or p=reject with pct=100, and you have a Verified Mark Certificate (VMC), receivers like Gmail display your brand logo in the inbox. For automated senders operating at scale, this is the last mile of authentication that makes messages visually trustworthy.
The DNS record:
default._bimi.yourdomain.com TXT "v=BIMI1; l=https://yourdomain.com/logo.svg; a=https://yourdomain.com/vmc.pem"
BIMI requires strict DMARC enforcement first. Don't pursue BIMI until your authentication chain is solid.
For agent-driven workloads where each message is programmatically generated and sent, the email infrastructure must have authentication baked into the sending path, not bolted on afterward. Configure DKIM signing at the infrastructure level, publish DMARC before the first send, and monitor aggregate reports continuously. Authentication failures in automated pipelines compound silently. By the time you notice declining deliverability, the reputation damage is already done.
Frequently Asked Questions
Does SPF alone satisfy DMARC requirements?
SPF alone can satisfy DMARC, but only if the MAIL FROM domain aligns with the From: header domain. Most automated senders use a different bounce domain for MAIL FROM, which breaks SPF alignment. In practice, DKIM alignment is more reliable for automated senders because it depends on your signing configuration, not your envelope sender domain.
What happens if I exceed the SPF 10-lookup limit?
The SPF evaluation returns a permerror. Most receiving MTAs treat permerror the same as an SPF failure. Under DMARC, SPF failing due to permerror means the SPF alignment check also fails. If DKIM also fails or isn't configured, DMARC applies your p= policy. Fix by flattening your SPF record to explicit ip4: ranges, eliminating chained include: directives.
Should I use p=reject immediately?
No. Start with p=none and a configured rua= aggregate reporting address. Run for at least two weeks, review the reports to find any legitimate sending sources you've missed, then move to p=quarantine for another cycle, then p=reject. Jumping straight to p=reject without visibility into your sending sources risks dropping legitimate mail from services you forgot to add to SPF or DKIM.
How does DKIM key length affect deliverability?
RSA-1024 bit keys are now considered weak and some receivers reject or downgrade messages signed with them — RFC 8301 recommends at least 2048 bits. RSA-2048 is the safe minimum today. Ed25519 keys are cryptographically stronger but receiver support isn't universal. Use RSA-2048 as your primary signing key.
Can an automated sender use multiple DKIM selectors?
Yes, and it's often useful. Different selectors let you rotate keys independently, attribute signing to different sending services, or experiment with Ed25519 alongside RSA. Each selector is a separate DNS TXT record. Receivers look up the selector specified in the s= tag of each message's DKIM-Signature header, so different messages can be signed with different keys simultaneously.
Do subdomains need their own DMARC records?
Only if you want a policy different from the organizational domain. Receivers fall back to the organizational domain's DMARC record for subdomains that don't have their own. Use the sp= tag on the organizational domain record to set an explicit subdomain policy without publishing individual records for every subdomain.