21 May 2026 · 14 min read
Amazon SES (Simple Email Service) is one of the cheapest, most scalable ways to send email, which is exactly why it shows up so often in the wild as both a legitimate sender and a favourite of spammers. If you send through SES and you want your mail to keep landing in the inbox at Gmail, Yahoo and Microsoft, you need SPF, DKIM and DMARC set up so that they actually align with your From domain. The defaults that SES gives you out of the box do not get you there on their own.
This guide is specific to Amazon SES. It covers the exact SPF include to publish, how to switch on Easy DKIM and what selectors SES uses, why the custom MAIL FROM (return-path) domain matters for SPF alignment, and the staged path to DMARC enforcement when SES is in your sending mix. If you want the general theory first, the glossary and our walkthrough on how to reach p=reject without breaking email are good companions, but everything below is written for SES.
What SES gives you by default, and why it is not enough
When you verify a domain in SES, you can send straightaway, but the headers tell a revealing story. By default:
- The envelope sender (the
MAIL FROM, also called the return-path or bounce address) is a subdomain ofamazonses.com, something like0000abcdef@eu-west-1.amazonses.com. - SPF therefore authenticates
amazonses.com, not your domain. - DKIM, if you have not enabled Easy DKIM, may not be signing with your domain at all.
That matters because DMARC does not care whether SPF or DKIM merely pass. It cares whether they pass and align with the domain in the visible From header. If your From is hello@yourdomain.com but SPF authenticates amazonses.com, that is an SPF pass with no alignment, which counts as an SPF failure for DMARC. The same logic applies to DKIM signed with an amazonses.com signing domain (d=amazonses.com) rather than d=yourdomain.com.
So the SES-specific work is not "turn on SPF and DKIM". It is "make SPF and DKIM authenticate your domain so they align under DMARC". Three pieces do that: the SPF include, Easy DKIM with CNAME records, and a custom MAIL FROM domain.
You can confirm exactly what is happening today with the DMARC checker for your policy, the SPF checker for your sending records, and the DKIM checker for your signatures. Run them before you change anything so you have a baseline.
SPF for Amazon SES: the exact include
Amazon SES publishes a regional SPF include. The mechanism you add to your domain's SPF record is:
include:amazonses.com
That single include covers SES sending across regions, so you do not normally need region-specific includes. A minimal SPF record for a domain that only sends through SES looks like this:
v=spf1 include:amazonses.com -all
If you also send through other services, you combine the includes. A domain sending through SES plus Google Workspace, for example:
v=spf1 include:amazonses.com include:_spf.google.com -all
A few SES-specific points that trip people up:
- Only publish SPF on the domain that appears in your MAIL FROM. This is the crucial subtlety. If you keep the SES default return-path, your
MAIL FROMis onamazonses.com, so SPF foramazonses.comis what gets checked, and your own SPF include does nothing for alignment. Theinclude:amazonses.comabove only earns you aligned SPF once you set a custom MAIL FROM on your own domain (covered below). Until then, SES SPF passes but does not align, and DMARC relies entirely on DKIM. - Stay under the ten-lookup limit. Each
includeconsumes DNS lookups, andinclude:amazonses.complus a few other senders can quietly push you past SPF's hard limit of ten DNS lookups, which produces apermerrorand an SPF failure. If you have stacked up marketing tools, CRMs and SES, check the count. We go deeper on this failure mode in SPF PermError: too many DNS lookups, and our SPF flattening product keeps the record flat and under the limit automatically. - Use
-all, not~all, once you are confident. A hard fail (-all) tells receivers to treat unlisted sources as unauthenticated. While you are still discovering senders,~all(softfail) is the cautious choice, but the end state for a locked-down domain is-all.
Publish one SPF record per domain only. Two separate v=spf1 TXT records on the same name is itself a permerror. The SPF generator will assemble a single valid record from your list of senders if you would rather not hand-edit.
Enabling DKIM in Amazon SES (Easy DKIM and BYODKIM)
DKIM is the part of SES authentication that is easiest to get aligned, and it is the one you should rely on most, because DKIM survives forwarding where SPF does not. SES offers two routes.
Easy DKIM (recommended)
Easy DKIM is Amazon's managed option. SES generates the key pair, holds the private key, signs your outbound mail and gives you three CNAME records to publish. The records look like this:
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx._domainkey.yourdomain.com CNAME xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.dkim.amazonses.com
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy._domainkey.yourdomain.com CNAME yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy.dkim.amazonses.com
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz._domainkey.yourdomain.com CNAME zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz.dkim.amazonses.com
The important detail for SES is that the selectors are opaque tokens that Amazon generates, not a friendly fixed name like selector1 or google. Each token is unique to your domain. Because SES publishes the public key on its side via the CNAME target, you never paste a p= public key into your zone. You publish three CNAMEs and SES handles key rotation behind them. That is genuinely convenient, and it means a future key rotation does not require a DNS change from you.
To enable it in the console: open the SES console, go to Verified identities, select your domain, open the DKIM tab, choose Easy DKIM, pick RSA 2048-bit (or 1024-bit if you have a legacy constraint), and SES will display the three CNAMEs. Add all three to your DNS exactly as shown. SES marks DKIM as "verified" once it can resolve them, which can take from a few minutes to a few hours depending on your DNS provider. Our note on how long DNS changes take sets expectations.
BYODKIM (bring your own DKIM)
If you have a compliance reason to control the private key, SES supports BYODKIM. You generate the RSA key pair yourself, publish a single TXT record at selector._domainkey.yourdomain.com containing the public key, and supply the private key and selector name to SES. With BYODKIM you choose the selector name, so you might use something like ses1. A BYODKIM public key record looks like a standard DKIM TXT record:
ses1._domainkey.yourdomain.com TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A..."
BYODKIM means you own key rotation, which is more control and more responsibility. For most senders Easy DKIM is the right call. Either way, the result you are aiming for is a DKIM signature where the signing domain (d=) is yourdomain.com. You can confirm the signature and selector your mail is actually using with the DKIM checker, and read the broader rationale on our DKIM product page.
The custom MAIL FROM domain: the SES detail that makes SPF align
This is the single most missed step in SES authentication, and the reason so many SES senders pass SPF yet still fail DMARC on the SPF side.
By default, SES sets the envelope sender to a region-specific subdomain of amazonses.com. When a receiver runs SPF, it checks the SPF record of amazonses.com, which passes, but that is Amazon's domain, not yours. There is no SPF alignment, because the domain SPF authenticated does not match your From header domain.
To fix it, configure a custom MAIL FROM domain in SES. You pick a subdomain of your own domain, typically bounce.yourdomain.com or mail.yourdomain.com, and SES asks you to publish two records: an MX record pointing the subdomain at the SES regional feedback endpoint, and an SPF (TXT) record authorising SES for that subdomain.
The MX record points at the SES inbound feedback host for your region. For eu-west-1 it looks like this:
bounce.yourdomain.com MX 10 feedback-smtp.eu-west-1.amazonses.com
For us-east-1 the host is feedback-smtp.us-east-1.amazonses.com, and so on per region. Alongside the MX, publish the SPF record for the MAIL FROM subdomain:
bounce.yourdomain.com TXT "v=spf1 include:amazonses.com -all"
Now the chain works. Your envelope sender becomes something@bounce.yourdomain.com, SPF authenticates bounce.yourdomain.com, and because that is an organisational-domain match with your From of hello@yourdomain.com, SPF aligns under DMARC's relaxed alignment (the default). DMARC's relaxed SPF alignment treats a subdomain like bounce.yourdomain.com as aligned with the parent yourdomain.com, which is exactly what you want.
One configuration choice to understand in SES: the MAIL FROM behaviour on MX failure. SES offers "Use the default MAIL FROM domain" or "Reject the message" if the custom MAIL FROM records cannot be resolved. Pick "Use the default" during rollout so a DNS hiccup does not stop your mail; you can tighten it later. The cost of "Use the default" is that, in that fallback state, you are back to non-aligned SPF, so do not leave broken records in place long term.
After this change, re-run the SPF checker against your MAIL FROM subdomain, and use the DMARC report analyzer once reports arrive to confirm SES traffic is now showing SPF aligned rather than just SPF pass.
Publishing DMARC for an SES-sending domain
With aligned DKIM (from Easy DKIM) and aligned SPF (from the custom MAIL FROM), you are ready to publish DMARC and begin monitoring. Start in observation mode. A starter record at _dmarc.yourdomain.com:
_dmarc.yourdomain.com TXT "v=DMARC1; p=none; rua=mailto:reports@yourdomain.com; ruf=mailto:reports@yourdomain.com; fo=1; adkim=r; aspf=r"
What each tag does here, in the SES context:
p=nonetells receivers to take no action yet and simply report. This is your listening phase. It does not protect you, but it is where you find out whether SES mail, and every other sender, is aligning.ruais where aggregate XML reports go. These reports are what reveal that SES is sending as you and whether those messages pass aligned SPF or DKIM. Point this at an address or tool that can parse them. Our monitoring does this and emails you plain-English summaries with change alerts.adkim=randaspf=rset relaxed alignment, which is what letsbounce.yourdomain.comcount as aligned withyourdomain.com. Do not setaspf=s(strict) unless your MAIL FROM domain exactly matches yourFromdomain, which with an SES bounce subdomain it will not.fo=1asks for a failure report whenever any underlying check fails, which speeds up debugging during rollout.
If you generate the record by hand, double-check the syntax with the DMARC generator and confirm it resolves with the DMARC checker. For the full breakdown of every tag, see our doc on understanding your DMARC record.
Reading your reports and reaching enforcement
Leave p=none running until you have a few weeks of aggregate reports. The reports group mail by source IP and tell you, per source, whether SPF and DKIM passed and whether they aligned. For SES, you are checking two things specifically:
- SES source IPs show DKIM aligned (
d=yourdomain.com). This proves Easy DKIM or BYODKIM is signing correctly. - SES source IPs show SPF aligned (envelope on
bounce.yourdomain.com). This proves your custom MAIL FROM is live.
If either is missing, fix it before tightening policy. Our guide to reading your first DMARC report walks through the XML, and the DMARC report analyzer turns those files into a readable per-source view so you are not parsing raw XML by hand.
Crucially, do not just look at SES. Aggregate reports surface every sender using your domain. With SES in the mix, common surprises include a separate transactional path through a different SES account or region, a marketing platform that was never aligned, or an old application server sending directly. Each of those needs to be aligned or removed before you reach p=reject, because at enforcement they will be the messages that get rejected. Our note on what to do when a service is not aligned at reject covers the triage.
When SES and every other legitimate source is aligning, move in stages. First to quarantine, ideally ramped with the percentage tag:
_dmarc.yourdomain.com TXT "v=DMARC1; p=quarantine; pct=25; rua=mailto:reports@yourdomain.com; adkim=r; aspf=r"
The pct=25 applies the policy to a quarter of failing mail, so you can watch the impact before committing fully. Raise it to pct=100, watch again, then move to full enforcement:
_dmarc.yourdomain.com TXT "v=DMARC1; p=reject; rua=mailto:reports@yourdomain.com; adkim=r; aspf=r"
At p=reject, forged mail claiming to be your domain, including spam sent through other SES accounts that are not yours, gets rejected outright, while your properly aligned SES mail sails through. That is the whole point of the exercise. The staged approach is the same one we describe in reaching p=reject without breaking email; the difference here is purely that you have verified SES alignment first.
SES-specific gotchas worth knowing
A handful of issues come up repeatedly with SES that are not obvious from the AWS console:
- Multiple regions, multiple identities. SES is regional. If you send from both
eu-west-1andus-east-1, you verify the domain and enable DKIM in each region, and each gives its own three CNAMEs. They can coexist in your zone. Your custom MAIL FROM MX record, however, points at one region's feedback host, so if you split sending across regions, plan how bounces are handled per region. - Sandbox versus production. New SES accounts start in sandbox mode, which only allows sending to verified addresses. Authentication still needs to be correct in sandbox, but you will not see meaningful DMARC report volume until you request production access and real traffic flows.
- Configuration sets and custom tracking domains. If you enable open and click tracking, SES rewrites links through a tracking domain. That is a separate CNAME and does not affect SPF, DKIM or DMARC alignment, but it is another DNS record people forget. It does not need to align for DMARC.
- The
amazonses.comDKIM signature is not enough. SES may add its ownd=amazonses.comsignature in addition to yours. That extra signature does nothing for your DMARC alignment; only thed=yourdomain.comsignature counts. Seeing two DKIM signatures in a header is normal and not a problem. - Shared IP pools. On SES shared IPs, your reputation is mostly your own because authentication ties mail to your domain, which is another reason getting DKIM and SPF alignment right matters more on SES than on a dedicated platform.
A clean SES authentication checklist
Putting it together, the records you should end up with for a domain that sends only through SES (region eu-west-1 shown) look like this:
; SPF on the MAIL FROM subdomain
bounce.yourdomain.com TXT "v=spf1 include:amazonses.com -all"
; MX for the MAIL FROM subdomain (bounce handling)
bounce.yourdomain.com MX 10 feedback-smtp.eu-west-1.amazonses.com
; Three Easy DKIM CNAMEs (tokens are unique to your domain)
<token1>._domainkey.yourdomain.com CNAME <token1>.dkim.amazonses.com
<token2>._domainkey.yourdomain.com CNAME <token2>.dkim.amazonses.com
<token3>._domainkey.yourdomain.com CNAME <token3>.dkim.amazonses.com
; SPF on the root if the From domain also sends directly
yourdomain.com TXT "v=spf1 include:amazonses.com -all"
; DMARC, starting in observation mode
_dmarc.yourdomain.com TXT "v=DMARC1; p=none; rua=mailto:reports@yourdomain.com; adkim=r; aspf=r"
Verify each piece with the relevant tool before you trust it: SPF checker, DKIM checker and DMARC checker. If you also publish MTA-STS for inbound TLS enforcement, that is independent of your SES sending setup but worth having on any production domain.
The practical takeaway
Amazon SES does not get you to DMARC enforcement for free. The defaults give you SPF on amazonses.com and possibly DKIM on amazonses.com, both of which pass but neither of which aligns with your From domain. The three SES-specific moves that fix it are: publish include:amazonses.com in SPF, enable Easy DKIM and publish its three CNAMEs so signing happens with d=yourdomain.com, and set a custom MAIL FROM domain so SPF authenticates a subdomain of yours instead of Amazon's. Once aggregate reports confirm SES is aligning on both SPF and DKIM, ramp from p=none to p=quarantine to p=reject and you have closed the door on anyone spoofing your domain through SES or anywhere else.
If you would rather not hand-manage CNAMEs, MAIL FROM records and the staged policy ramp across every domain you own, that is exactly what our done-for-you service handles: we host the records, watch the reports, alert you when a sender drifts out of alignment, and take you safely from p=none to p=reject with no email outage. Start by running your domain through the DMARC checker, or see the requirements the mailbox providers now enforce.