How to Set Up SPF, DKIM, and DMARC Records — The Basics

New to email sending? These are the 3 DNS records you absolutely need before sending a single campaign. This guide is the basics — what each does, what to publish, how AcelleMail verifies them.

The 3 must-have records

Email deliverability has many factors. The 3 DNS records you MUST have to send legitimate email at any volume:

Record What it does
SPF (TXT) Tells receiving servers which IPs are authorized to send for your domain
DKIM (TXT or CNAME) Cryptographically signs your emails so receivers can verify they're really from you
DMARC (TXT) Tells receivers what to do when SPF or DKIM check fails

Without ALL THREE, your emails go to spam (or worse — blocked entirely).

AcelleMail's verify-domain wizard generates these for you

You don't write SPF / DKIM / DMARC from scratch. AcelleMail's wizard generates the records based on your sending vendor + setup.

Open the sending-domain detail

In AcelleMail's sidebar, Sending → Sending domains. The list shows every domain you've registered with status chips (Verified / Pending / Failed) and per-auth indicators:

Sending domains list

Click into your domain row. The detail page surfaces exactly which DNS records to publish (TXT for SPF, CNAMEs for DKIM, TXT for DMARC) with copy-paste-ready values + current verification state per check:

Sending-domain detail — DNS records + auth status

The sending-domain detail page shows you the EXACT records to publish at your DNS host. Click "Show DNS records" — copy each line, paste into your DNS provider (Cloudflare, Route 53, Namecheap, etc.) as a new record.

After publishing, click Verify domain in AcelleMail. The dig-check confirms each record is reachable + correctly formatted.

What you'll publish

SPF (TXT record at apex)

Type:  TXT
Name:  yourdomain.com  (the root — no subdomain)
Value: v=spf1 include:amazonses.com -all
TTL:   3600

Replace amazonses.com with whatever vendor you use:

  • Amazon SES → include:amazonses.com
  • Mailgun → include:_spf.mailgun.org
  • SendGrid → include:sendgrid.net
  • Postmark → include:spf.mtasv.net

Combine for multi-vendor:

v=spf1 include:amazonses.com include:_spf.mailgun.org -all

-all tells receivers to REJECT mail from any IP not in your SPF. Use ~all while testing; switch to -all once production-stable.

DKIM (CNAME or TXT)

AcelleMail generates a keypair when you add a sending domain. The publish is typically:

Type:  CNAME
Name:  acellemail._domainkey.yourdomain.com
Value: acellemail._domainkey.acellemail.com
TTL:   3600

The selector (acellemail) and target are shown in your sending-domain detail page.

DMARC (TXT at _dmarc subdomain)

Start in monitor mode:

Type:  TXT
Name:  _dmarc.yourdomain.com
Value: v=DMARC1; p=none; rua=mailto:dmarc-reports@yourdomain.com
TTL:   3600

Key parts:

  • p=none — monitor only (no enforcement); collect aggregate reports for 30+ days
  • rua=mailto:... — where to send aggregate reports

After 30 days of clean reports, step up to p=quarantine and eventually p=reject. See DMARC enforcement migration for the staged plan.

Verify in AcelleMail

After publishing all 3 records, return to AcelleMail and click Verify domain. The auth chips:

The auth chips on the sending-server detail

Open Settings → Sending servers → click your active server. The toolbar shows the live SPF / DKIM / DMARC chip status:

Sending server detail with auth chips

  • Green chips on all three = receiving servers can confirm you're authorized to send from this domain.
  • Any chip red = receiving servers immediately downgrade reputation. Click Verify domain in the toolbar to walk through the DNS-fix wizard.

All three should turn Green within minutes (depending on DNS propagation speed). If any stays Red:

  • Check the record at your DNS host (typo? wrong record type?)
  • Wait — DNS takes 5-60 minutes typically, up to 24h for stubborn caches
  • Use dig from your terminal to verify the record IS published: dig TXT yourdomain.com +short

Common questions

Question Answer
Can I have multiple SPF records? NO. Receivers accept only one TXT starting with v=spf1. Combine includes.
Where does the DKIM key go on my DNS? Wherever your sending-domain detail page tells you (usually CNAME at {selector}._domainkey.yourdomain.com)
Should p= be none, quarantine, or reject? Start with none (monitor). Move up gradually.
What happens if I skip DMARC? Receivers fall back to general spam filtering; your reputation builds slower
My DNS host doesn't accept TXT >255 chars Split via quoted-string concatenation: "v=spf1 ..." "..." "..."
When can I add BIMI? After DMARC reaches p=quarantine or p=reject — see BIMI setup

Common UI signals + fixes

Symptom Likely cause UI fix
Verify-domain stays Pending Records not yet propagated Wait up to 24h; verify with dig from terminal
SPF chip Red despite published record Syntax error (e.g. ~all typo, missing v=spf1) Re-copy exact value from AcelleMail's wizard
DKIM chip Red despite CNAME CNAME pointing to wrong target Verify selector + target match AcelleMail's wizard
DMARC chip Red TXT record name not _dmarc.yourdomain.com (typo) Re-publish at correct name
All Green but emails still go to spam Reputation/content issue, not auth See Sender reputation monitoring
Records show "MULTIPLE" warning Two SPF records published — receivers reject Delete duplicate; keep one combined record
Advanced: 2048-bit DKIM, DMARC subdomain policies, vendor-specific gotchas

2048-bit DKIM is the modern standard. Some DNS hosts have TXT record character limits — if your DKIM record is >255 chars, you may need to:

  • Switch to CNAME (recommended; AcelleMail's default)
  • Use quoted-string concatenation: "v=DKIM1; k=rsa; p=ABC..." "...DEF"

DMARC subdomain policies via sp=:

v=DMARC1; p=none; sp=reject; rua=mailto:...

p=none (apex policy) but sp=reject (subdomain policy = strict). Useful when you want apex in monitor mode but subdomains in strict.

Vendor-specific SPF gotchas:

Amazon SES (multi-region):  include:amazonses.com   (covers all regions)
SES dedicated IP:           include:amazonses.com   (same — uses shared SES MX)
SendGrid (specific subaccount): include:u123456.sendgrid.net  (per-subaccount)
Mailgun (EU region):        include:_spf.eu.mailgun.org

Multi-vendor SPF combine:

v=spf1 include:amazonses.com include:_spf.mailgun.org include:sendgrid.net -all

Stay under 10 DNS lookups total (see SPF record deep dive for the math).

Per-customer DKIM (SaaS):

For SaaS sending-on-behalf, customers add their own DKIM CNAME. Your platform exposes the CNAME via the sending-domain detail page; customer publishes at their DNS host.

DKIM rotation:

Industry standard: rotate DKIM key every 6-12 months. AcelleMail's admin → Sending → DKIM Key Rotation generates a new keypair + updates the CNAME target. Old keys remain valid for 30 days during transition (so in-flight messages don't fail signature check). See DKIM key rotation playbook.

Test before going live:

mail-tester.com — free service. Send a test email to a generated address; receive a deliverability report:

  • SPF: pass/fail + reason
  • DKIM: pass/fail + reason
  • DMARC: pass/fail + reason
  • Spam score: 0-10 (10 = perfect)

Aim for 9.0+. Below 8.0, fix issues before live sending.

Related articles

5 commenti

4 commenti

  1. lequan.saigon
    the SPF flattening explanation finally made it click for me. I'd been hitting the 10-lookup limit and didn't understand why nesting includes counted.
  2. tnovak.cz
    What's your recommendation for sub-domains? We send from mail.example.com AND notifications.example.com. Same DKIM selector or separate?
    1. admin
      right — for rds specifically, you can change wait_timeout via the parameter group without a reboot if it's set as 'dynamic'. most defaults are.
  3. cmendoza.mx
    worth noting: our DNS provider (Cloudflare) caches negative responses for 1 hour. We added a TXT record, dig showed it, but mail-tester said missing for another 40 minutes. Almost lost our minds. TTL was set to 300 but the parent zone NS cache held...
  4. tranminh.devop…
    Our DKIM rotation broke for 2 days because we updated the active selector first, then waited to delete the old. Should be the other way — publish new, wait 48h for cache, switch sending, THEN remove old.

More in DNS & Domain Setup