5 · DNS email records
Objective — make transactional email deliverable by authenticating the sending domain: verify the provider, add SPF/DKIM/DMARC (plus MX), interpret CAA safely, and confirm with dig — so password resets, receipts, and notifications don’t land in spam or get rejected.
Steps at a glance:
- Verify the email provider and record credentials — Confirm which service sends mail (Postmark, SES, Mailgun, SendGrid, your host’s SMTP) and that the domain is verified there.
- Add the three records and understand what each does — publish SPF, DKIM, and DMARC records, so outbound email can pass authentication instead of landing in spam.
- Add MX records (if the domain receives mail) — If the domain also receives mail, add the provider’s MX records at the documented priorities. If it only sends (transactional-only), MX may point elsewhere or be omitted — match your provider’s guidance.
- Interpret CAA safely — empty CAA is fine; Cloudflare-managed permissive multi-issuer CAA is also fine. Flag restrictive single-issuer records before final certificate strategy.
- Verify with
dig— Read the resolver output directly and record the Phase 12 live-mail proof owner.
Background
Section titled “Background”flowchart LR App[Laravel mailer] --> ESP[Email provider] ESP --> DNS[SPF + DKIM + DMARC DNS] DNS --> Inbox[Recipient inbox] DNS --> Reject[Reject / spam folder]1. Verify the email provider and record credentials
Section titled “1. Verify the email provider and record credentials”Confirm which service sends mail (Postmark, SES, Mailgun, SendGrid, your host’s SMTP) and that the domain is verified there.
Record the SMTP/API credentials into the production .env (MAIL_*) from 3 · Production .env — double-quoted, never committed.
2. Add the three records and understand what each does
Section titled “2. Add the three records and understand what each does”| Record | Type | Answers | Without it |
|---|---|---|---|
| SPF | TXT | Which servers may send for this domain | Mail flagged as spoofed |
| DKIM | TXT | Cryptographic signature proving integrity | Tampering undetectable; spam scoring |
| DMARC | TXT | Policy when SPF/DKIM fail + where to report | No alignment policy; inconsistent delivery |
-
Publish the SPF record — one
TXTat the root, listing every sender. Merge into a single record — multiple SPF records is itself a failure.DNS records example.com. TXT "v=spf1 include:_spf.provider.com ~all"- ✅ A single SPF
TXTrecord exists at the root, listing every sender.
- ✅ A single SPF
-
Publish the DKIM record — your provider gives a selector and key; publish it at the selector host they specify.
DNS records selector._domainkey.example.com. TXT "v=DKIM1; k=rsa; p=<public-key>"- ✅ The DKIM key is published at the provider’s selector host.
-
Publish the DMARC record — start at
p=none(monitor only), collect reports, then tighten toquarantine/reject.DNS records _dmarc.example.com. TXT "v=DMARC1; p=none; rua=mailto:dmarc@example.com; fo=1"- ✅ A DMARC
TXTrecord at_dmarc.<domain>starts atp=none.
- ✅ A DMARC
3. Add MX records (if the domain receives mail)
Section titled “3. Add MX records (if the domain receives mail)”If the domain also receives mail, add the provider’s MX records at the documented priorities. If it only sends (transactional-only), MX may point elsewhere or be omitted — match your provider’s guidance.
-
Publish the MX records at the provider’s priorities.
DNS records example.com. MX 10 mx1.provider.com.example.com. MX 20 mx2.provider.com.- ✅ MX records are present if the domain receives mail (or correctly omitted if send-only).
4. Interpret CAA safely
Section titled “4. Interpret CAA safely”CAA records restrict which certificate authorities may issue for the domain. The risk is not “CAA exists”; the risk is a restrictive record that excludes the issuer your final SSL path uses.
5. Verify with dig
Section titled “5. Verify with dig”Read the resolver output directly. Do not treat a real test email as Phase 4 work — that is [RUN-LIVE] proof and belongs in production after the app can actually send mail.
-
Confirm all records resolve.
Terminal window dig +short TXT example.com | grep spf1 # SPF present, single recorddig +short TXT selector._domainkey.example.com # DKIM key resolvesdig +short TXT _dmarc.example.com | grep DMARC1 # DMARC policy presentdig +short MX example.com # MX (if receiving mail)# Expected: one SPF line, the DKIM key, a DMARC1 policy, and MX records (if receiving mail)- ✅ SPF (single), DKIM, DMARC, and MX (if receiving) all resolve.
-
Record the live-mail proof owner. The real send/receive test happens in Phase 12 Step 3 · Harden, verify & sync after production SMTP settings and the live app exist.
- ✅ Phase 12 owns the live mail-header proof; Phase 4 owns DNS record resolution only.
Troubleshooting
Section titled “Troubleshooting”| Symptom | Cause | Fix |
|---|---|---|
spf=softfail/fail | Sender not in SPF include | Add the provider’s include; keep one SPF record |
dkim=none | Selector record missing/typo’d | Re-publish exactly as the provider specifies |
dmarc ignored | Record at wrong host | Must be _dmarc.<domain>, not the root |
| Multiple SPF records | Two TXT v=spf1 entries | Merge into one |
| Restrictive CAA before cert strategy | Only one CA is allowed and it is not your active/final issuer | Add the intended issuer now, or add a Zaj-BACKLOG.md Phase 7 renewal-monitoring row with owner, trigger, and acceptance |
Checklist
Section titled “Checklist”Do not mark this step done until every box below is checked.
- 👤 Provider verified — email provider verified;
MAIL_*recorded in production.env. - 🔀 Records resolve — SPF (single record), DKIM selector, and DMARC (
p=noneto start) all resolve viadig. - 👤 MX correct — MX records correct if the domain receives mail.
- 🤖 CAA interpreted — CAA is empty/permissive, or restrictive CAA has a named
Zaj-BACKLOG.mdcert-strategy follow-up before Phase 7 hardening. - 🤖 RUN-LIVE owner recorded — real mail-header proof is assigned to Phase 12 after production can send mail.