Amazon SES SPF, DKIM, DMARC Setup: Alignment Guide

Set up SPF, DKIM, and DMARC for Amazon SES: Easy DKIM CNAMEs, a custom MAIL FROM subdomain, and the alignment failure that passes checks but fails DMARC.

Amazon SES SPF, DKIM, DMARC Setup — and the Alignment Mistake That Eats Deliverability

Amazon SES makes the hard part (cheap, scalable sending) easy and the easy-looking part (sender authentication) silently hard. I say "silently" because the failure mode doesn't announce itself: your SES console shows the domain identity as verified, your mail goes out, and a portion of it lands in spam — not because your list is bad, but because your SPF, DKIM, and DMARC were never actually aligned.

I learned this on the receiving end of my own bounce catastrophe. My list hadn't died from spam complaints — it had died from a sending pause, and when I resumed, the first send bounced above the prediction and the account got suspended. That disaster taught me the discipline that now runs through everything I ship: check before you send. Sender authentication is the first of those checks, and it's where most SES senders fail before a single recipient is even in the picture.

Here's the full setup, the order that matters, and the one mistake that undoes the rest.

What each record actually does

Short version first, because mixing these up is how the mistakes happen:

  • SPF answers: which servers are allowed to send mail for this domain?
  • DKIM answers: was this message signed by someone who holds the domain's private key — and did it arrive unaltered?
  • DMARC answers: what should receivers do when SPF or DKIM fail, and how do they report back?

DMARC has one more job that trips up almost everyone: alignment. Passing SPF or DKIM isn't enough — DMARC requires that the domain that passed matches your visible From: domain. This is where the classic SES footgun lives (below).

Step 1: DKIM via Easy DKIM (your domain's signature, not Amazon's)

In the SES console, open your verified domain identity, go to Authentication, and enable Easy DKIM. SES generates three CNAME records for your domain (Amazon SES looks for exactly three unique CNAME records to mark DKIM authentication as successful) — copy the exact values and publish them in your DNS. This is the most important step in the list, and here's why: without your own DKIM signature, your mail is signed by amazonses.com. DKIM "passes" in that case — but the signature is for Amazon's domain, not yours, and DMARC alignment against your From: domain fails. The mail goes out, the checks look green in the console, and receivers quietly downgrade you. A recent sender-auth guide on dev.to (crawled yesterday) makes exactly this point: alignment fails when the authenticated domain doesn't match the From: domain, and the fix is either signing with your own domain or setting the relay to use an aligned custom MAIL FROM.

So: Easy DKIM first. Wait until the identity shows successful — then remember palisade.email's warning, published ~37 days ago and still the sharpest line on this topic: a successful SES identity status does not prove that a production message is signed, SPF-authenticated, or DMARC-aligned. Verify the DNS, the identity state, a newly delivered message, and DMARC reports separately.

Step 2: Custom MAIL FROM domain (SPF alignment)

By default, SES uses an amazonses.com MAIL FROM domain. That works — but for DMARC alignment, the envelope sender should live under your own domain structure. In the identity settings, enable a custom MAIL FROM domain (something like mail.yourdomain.com), and publish the MX and SPF TXT records SES supplies for that subdomain.

Two SPF rules that are non-negotiable:

  1. One SPF record per domain. Merge, don't stack. If you already send from Google Workspace, a CRM, or anything else, do not publish a second SPF record alongside it — merge the includes into a single record (a medium.com SES walkthrough makes this the #1 SPF mistake, and it matches everything I've seen in the field). Two SPF records = broken SPF.
  2. Don't add include:amazonses.com to your root-domain SPF record unless the setup requires it there. With a custom MAIL FROM subdomain, the SPF for your SES mail lives on the subdomain — the root record is for everything else. A recent palisade.email guide (updated ~37 days ago) flags exactly this: people cargo-cult the SES include into the root record and gain nothing from it.

Step 3: DMARC, starting at p=none

Publish a DMARC record at _dmarc.yourdomain.com. Start with a monitoring policy:

v=DMARC1; p=none; rua=mailto:dmarc-reports@yourdomain.com; pct=100

p=none is intentional while you're warming up — you want the aggregate reports flowing in so you can see whether SPF and DKIM are actually passing and aligned on real mail. Once your reports show consistent passes, move to p=quarantine. Do not start at p=reject — you'll reject mail you didn't intend to while you're still debugging alignment.

Step 4: Verify like you mean it (the four separate checks)

This is the step almost nobody completes, and it's the whole point of the article:

  1. DNS records — dig the DKIM selectors, the MAIL FROM MX/TXT, the DMARC record. Public DNS, not your provider's cached dashboard view.
  2. SES identity state — successful is necessary, not sufficient.
  3. A real delivered message — send to a seed inbox, read the raw Authentication-Results header. You want spf=pass, dkim=pass, and dmarc=pass — all three, on one message.
  4. DMARC aggregate reports — the rua mailbox tells you the truth over time: what percentage of your mail actually passes aligned authentication. This is the report that would have caught my alignment problem before the first real send.

If any of these four fails while the others pass, you have a configuration bug, not a reputation problem — fix it before you touch your list.

The one mistake that undoes the rest

The SES console's green checkmarks measure configuration, not deliverability. A verified identity with unaligned DKIM and a default MAIL FROM sends mail that passes the individual checks while failing DMARC alignment — the exact failure that pushes mail to spam without a single bounce or complaint to show for it. You won't see it in your bounce rate. You'll see it as "deliverability just seems off."

This is why the discipline matters: check before you send, on real mail, against public records — not in a console.

When the stakes are bigger than a DNS record

Sender authentication is necessary but not sufficient. A perfectly authenticated domain will still die on the vine if the list behind it is rotten: dead addresses from a sending pause, disposable mailboxes, duplicate imports, addresses already flagged as bounces or complaints elsewhere. The authentication gets you past the door; the list quality determines what happens inside.

That last category — 5,000+ addresses, a months-long sending pause, an inherited list, a first send that determines whether the account survives the week — is what a pre-send audit exists for. The audit is a fixed-scope, 7-day engagement: your list screened through the full offline pipeline (syntax, disposable, role, duplicate, suppression), sender setup (SPF/DKIM/DMARC) checked against public DNS records, a stated prediction figure for what your bounce rate would be if you sent today, and a flagged-address report with reasons — all without sending a single message to your list. One honest boundary: mailbox-level SMTP probing is not part of a standard pre-send screen — we don't sell stages we haven't built.

The guarantee is deliberately weak, because anything stronger would be dishonest: if your first send bounces above the prediction, we re-run the analysis free — within 30 days of receiving the audit findings. And the audit fee is credited in full toward a rescue tier within 30 days if the audit shows you need the bigger fix. Manual invoice default; pricing and terms in writing.

My account died because nobody checked before the first send after a pause. Check the DNS. Check the list. Then send.

Keep Exploring

Use the Workflow Library to browse more guides, comparisons, and integration examples to continue your evaluation.