Adding DMARC, SPF, and DKIM records in AWS Route 53

Route 53 has two rules that trip people up: TXT values must be wrapped in double quotes, and the apex record name is left blank, never @. Here is the console path, the quirks, and the least-privilege IAM if you would rather connect us for one-click instead.

The shortcut: connect once, never touch the console

Route 53 is one of the providers trustyourinbox can write to directly. If you connect a scoped, API-only IAM user, every DMARC, SPF, DKIM, and TLS-RPT fix we recommend becomes one click, with a five-minute cancel window and a 24-hour undo. Connecting Route 53 takes about five minutes and is the path we recommend. The rest of this guide is for when you would rather publish records by hand.

Before you start: confirm Route 53 answers your DNS

Route 53 assigns each hosted zone four nameservers spread across four top-level domains (.com, .net, .org, .co.uk) for resilience, looking like ns-2048.awsdns-64.com. Confirm your domain is delegated to them:

dig +short NS yourdomain.com

If the answers contain awsdns, you are in the right place. If not, the zone you are editing is not the one answering live queries.

Step 1: Open the hosted zone

  1. Open the Route 53 console.
  2. In the navigation pane choose Hosted zones.
  3. Choose the name of the hosted zone for your domain.
  4. Choose Create record. Keep the default Simple routing (the weighted and latency policies are for load balancing, never for email-auth records).

Step 2: Create the record

Two Route 53 rules govern every record below. First, wrap the value in double quotes in the Value box. Second, for the apex (your SPF record), leave the Record name field blank. Do not type @; Route 53 would treat it as a literal label. The greyed suffix already shows your domain, so you type only the prefix for everything else.

DMARC

Record name: _dmarc
Record type: TXT
Value:       "v=DMARC1; p=none; rua=mailto:you@yourdomain.com"
TTL:         300

Start at p=none, then move past p=none once your reports are clean. The quotes are part of what you paste.

SPF

Record name: (leave blank for the apex)
Record type: TXT
Value:       "v=spf1 include:_spf.yourprovider.com ~all"
TTL:         300

Publish only one v=spf1 record. If the apex already has a TXT record with an SPF string, edit that record rather than adding a second. Our SPF builder keeps you under the ten-lookup limit.

DKIM (the multi-string part)

A single TXT string maxes out at 255 characters, and a 2048-bit DKIM key is longer than that. Route 53 does not split it for you, so you break the key into chunks of 255 or fewer, wrap each chunk in its own double quotes, and put them all on one line separated by spaces:

Record name: selector._domainkey
Record type: TXT
Value:       "v=DKIM1; k=rsa; p=MIIBIjANBgkq...first255" "...rest of the key"
TTL:         300

The strings concatenate back together at lookup time. The chunks of one key go on a single line separated by spaces, not on separate rows (separate rows would be separate TXT records). The total value can be up to 4000 characters.

MTA-STS pointer

Record name: _mta-sts
Record type: TXT
Value:       "v=STSv1; id=20260623000000"
TTL:         300

This is the pointer only. The policy file is served over HTTPS at mta-sts.yourdomain.com, which trustyourinbox can host. TLS-RPT (_smtp._tls) follows the same quoted-TXT shape.

When everything is filled in, choose Create records (the final button is plural).

Route 53 quirks that bite

  • Forgetting the quotes. An unquoted TXT value either errors or stores wrong. Every value goes in double quotes.
  • Typing @ for the apex. Leave Record name blank instead. @ becomes a literal record at @.yourdomain.com.
  • Splitting a DKIM key across rows. Chunks of one key are space-separated on one line. Separate rows create separate records.
  • Picking a long initial TTL. 300 seconds keeps corrections fast while you test. Raise it once the records are stable.

Least-privilege IAM (if you script it)

Editing records needs four actions: route53:ChangeResourceRecordSets and route53:ListResourceRecordSets (scoped to the hosted-zone ARN arn:aws:route53:::hostedzone/YOUR_ZONE_ID), plus route53:GetHostedZone and route53:ListHostedZones to find the zone. The managed AmazonRoute53FullAccess policy is the easy path but grants everything across every zone; AWS itself recommends a scoped customer-managed policy for least privilege. That same scoped user is exactly what our one-click connection uses.

Step 3: Verify it published

dig +short TXT _dmarc.yourdomain.com
dig +short TXT yourdomain.com | grep spf1
dig +short TXT selector._domainkey.yourdomain.com

Or paste the hostname into dns.google with type TXT. The double quotes you entered will not appear in the lookup output; resolvers strip them, which is expected.

Tell trustyourinbox to recheck

Each per-domain protocol tab has a Recheck button next to the current record. Click it once the Route 53 change resolves and we re-run the lookup and refresh the dashboard.

Keep reading

Last verified 2026-06-23 against the official AWS Route 53 documentation.

Stop guessing. Start monitoring.

Free for one domain. Set up in five minutes. We parse the reports; you read plain-English summaries.