DMARC for Transactional Email: SendGrid, Mailgun, Amazon SES, Postmark, SparkPost, Mailjet, Resend, MailerSend, Brevo — Custom-Domain DKIM, Return-Path Alignment, and ESP Selector Conventions

The deployment guide for DMARC on transactional email sent through third-party ESPs (SendGrid, Mailgun, Amazon SES, Postmark, SparkPost, Mailjet, Resend, MailerSend, Brevo): why SPF alignment is unreliable for ESPs, the CNAME-delegated custom-domain DKIM path as the load-bearing alignment mechanism, per-ESP selector conventions, Return-Path configuration for secondary SPF alignment, dedicated-subdomain segmentation, multi-ESP authentication strategies, dedicated vs shared IP implications, and the Feb 2024 Google / Yahoo bulk-sender requirements anchor.

This deployment guide is provided in English. ESP / DMARC / DKIM operational vocabulary (Easy DKIM, custom-domain DKIM, CNAME delegation, Return-Path, envelope MAIL FROM, header From, sender signature, configuration set, dedicated IP, shared IP, IP warmup, bounce domain) and the per-ESP selector / hostname identifiers (s1._domainkey, s2._domainkey, mailo._domainkey, mta._domainkey, scph0316._domainkey, mailjet._domainkey, resend._domainkey, mlsend._domainkey, mlsend2._domainkey, amazonses.com, sendgrid.net, mailgun.org) are vendor-canonical terms that do not translate. We keep the body in the source language so the configuration values remain copy-paste safe across locales.

TL;DR

  • DKIM is the load-bearing alignment mechanism for transactional email, not SPF. Most ESPs (SendGrid, Mailgun, Amazon SES, SparkPost) rewrite the envelope MAIL FROM to a bounce-handling domain under their control, so SPF aligns with that domain rather than with your visible From: header. DKIM with a custom-domain selector is what makes DMARC pass.
  • Every ESP has its own DKIM selector convention. SendGrid uses s1._domainkey + s2._domainkey (rotating pair); Mailgun uses mailo._domainkey (newer) or mta._domainkey (legacy); Amazon SES Easy DKIM uses three random <token>._domainkey CNAMEs; Postmark uses a date-named selector TXT record; SparkPost uses scph0316._domainkey; Mailjet uses mailjet._domainkey; Resend uses resend._domainkey.
  • Publish all CNAMEs as the ESP instructs, then verify with dig. A typical verification command is dig +short cname s1._domainkey.your-domain.com for SendGrid or dig +short txt mailo._domainkey.your-domain.com for Mailgun.
  • Use a dedicated subdomain for transactional mail - transactional.example.com, mail.example.com, or mg.example.com isolates reputation from corporate mail (Workspace / M365) and marketing mail. Independent DMARC policy via the np= / sp= tags lets the apex ramp p=reject while a subdomain remains at p=none during ESP onboarding.
  • Configure a custom Return-Path / bounce subdomain (em.your-domain.com, bounces.your-domain.com, or mailo.your-domain.com) as a CNAME to the ESP's bounce hostname to enable SPF alignment as a SECONDARY path - DKIM remains primary. SendGrid, Mailgun, and Amazon SES all support this; Postmark handles bounces internally so the custom Return-Path step is not applicable.
  • The Feb 2024 Google / Yahoo bulk-sender requirements mandate DMARC at p=quarantine or stricter for senders above 5000 messages/day. Transactional senders routinely exceed this threshold; deferred deliverability or bulk foldering at scale is the consequence of missing DMARC alignment.
  • Watch the SPF 10-DNS-lookup limit (RFC 7208 section 4.6.4) when adding multiple ESP includes to the apex SPF record. include:sendgrid.net + include:mailgun.org + include:amazonses.com + include:_spf.google.com already consumes 4-6 lookups before counting redirects. Dedicated subdomains per ESP keep each SPF record under the limit.
  • The DMARC Analyzer dashboard surfaces per-source-IP alignment per ESP via source_ip_detail.php + reporter_detail.php. Use it to verify each ESP's outbound IP range is producing aligned messages before advancing the DMARC policy.

1. What this guide covers

This guide is the operator walkthrough for deploying SPF, DKIM, and DMARC on a domain whose transactional email is sent by a third-party Email Service Provider (ESP). The page covers the ten most-deployed ESPs in 2026:

  • Twilio SendGrid - the largest transactional-email platform by volume. Authenticated Domain CNAMEs at em.<your-domain>, s1._domainkey.<your-domain>, s2._domainkey.<your-domain>.
  • Mailgun (Sinch) - the developer-focused API platform with regional EU / US infrastructure. DKIM CNAME at mailo._domainkey.<your-domain> (newer accounts) or mta._domainkey / pic._domainkey (legacy).
  • Amazon SES (Simple Email Service) - the AWS transactional-email platform. Easy DKIM generates three random <token>._domainkey CNAMEs pointing to <token>.dkim.amazonses.com. Optional custom MAIL FROM at mail.<your-domain>.
  • Postmark (ActiveCampaign) - transactional-only, optimized for fast delivery and high inbox placement. DKIM published as a TXT record (NOT a CNAME) at <selector>._domainkey.<your-domain> where the selector is the literal date or the Sender Signature name.
  • SparkPost (MessageBird) - the enterprise transactional platform with bring-your-own-infrastructure deployment. DKIM CNAME at scph0316._domainkey.<your-domain>.
  • Mailjet (Sinch) - the European transactional-email platform with EU-residency guarantees. DKIM CNAME at mailjet._domainkey.<your-domain>.
  • Sendinblue / Brevo - the European all-in-one (transactional + marketing) platform. DKIM CNAME at mail._domainkey.<your-domain> and a TXT record at brevo-code:<hash> for domain verification.
  • Resend - the developer-API platform built by the React Email team. DKIM CNAME at resend._domainkey.<your-domain>.
  • MailerSend - the transactional-and-marketing platform with Inbound Routing support. DKIM CNAMEs at mlsend._domainkey.<your-domain> and mlsend2._domainkey.<your-domain>.
  • Mandrill (Mailchimp transactional) - the transactional add-on to the Mailchimp marketing platform. DKIM uses the Mailchimp domain authentication CNAMEs at k1._domainkey.<your-domain> and k2._domainkey.<your-domain>.

Beyond these ten the same universal pattern applies to Pepipost / Netcore, Elastic Email, SocketLabs, SMTP2GO, Mailtrap, SES Lite, and any other ESP that supports custom-domain authentication: a DKIM CNAME (or TXT) at an ESP-specified selector pointing to the ESP's key infrastructure, optional Return-Path / bounce subdomain CNAME, and an SPF include at the apex.

Companion pages: the four mailbox-provider deployment guides (DMARC for Google Workspace, DMARC for Microsoft 365, DMARC for cPanel & Shared Hosting, DMARC for Plesk, DirectAdmin, ISPConfig) cover the OUTBOUND MTA you control. This page covers the OUTBOUND MTA an ESP runs for you.

2. Why transactional email needs different DMARC handling

Transactional email differs from mailbox-provider outbound mail in three ways that fundamentally change the DMARC deployment surface.

2.1 Envelope MAIL FROM rewriting (the SPF alignment break)

When you send mail through Google Workspace, Microsoft 365, or your own Postfix / Exim MTA, the envelope MAIL FROM (RFC 5321 section 4.1.1.2) and the visible header From: (RFC 5322 section 3.6.2) are typically the same domain - your-domain.com sends on behalf of your-domain.com, and SPF aligns natively. When you send mail through an ESP, the ESP rewrites the envelope MAIL FROM to a domain it controls (typically bounces.sendgrid.net, bounce.mailgun.org, or <region>.amazonses.com) so the ESP can handle delivery failures via its own bounce-processing infrastructure. SPF authentication passes for the ESP's bounce domain against the ESP's published SPF record - but DMARC's identifier alignment requirement compares the SPF-authenticated domain against the header From: domain, and the two no longer match.

Result: the message passes SPF authentication but fails SPF alignment, which fails DMARC unless DKIM alignment succeeds independently.

2.2 Shared signing infrastructure (the DKIM custom-domain requirement)

By default an ESP signs every outbound message with its own signing domain (d=sendgrid.net, d=mailgun.org, d=amazonses.com). This satisfies the ESP's deliverability but does NOT align with your header From: domain - the receiver sees a DKIM signature valid for the ESP, but DMARC requires the DKIM d= to match (in relaxed alignment) or exactly equal (in strict alignment) your-domain.com.

The fix is custom-domain DKIM: you publish a CNAME at the ESP-specified selector under your-domain.com pointing to the ESP's key infrastructure. The ESP signs your outbound messages with d=your-domain.com s=<esp-selector>, the receiver follows the CNAME to fetch the public key from the ESP, and DKIM aligns with the header From:. The private key never leaves the ESP - the CNAME delegation is purely a public-key-lookup redirection.

2.3 Feb 2024 Google / Yahoo bulk-sender requirements

Effective February 2024, Google and Yahoo require senders above 5000 messages/day to Gmail / Yahoo Mail to publish DMARC at p=quarantine or stricter, maintain SPF + DKIM alignment, configure one-click unsubscribe per RFC 8058, keep complaint rates below 0.1 percent, and use a custom Return-Path / bounce domain. Transactional senders routinely exceed 5000 messages/day in production deployments. Failing the bulk-sender requirements results in:

  • Deferred delivery (4xx temp-fail) at receiver scale, raising your apparent latency to end users.
  • Bulk-folder routing for messages that pass the spam filter but fail the bulk-sender checks - users never see the password reset because Gmail filed it under Promotions.
  • Outright reject (5xx perm-fail) when the Feb 2024 requirements are missed badly enough - typically only when DMARC is at p=none AND SPF / DKIM are both unaligned.

DMARC alignment for transactional email is no longer a security-only concern; it is a deliverability requirement at scale.

3. The SPF alignment trap

The most common DMARC failure mode for transactional email is SPF passes but DMARC fails. Operators see SPF=pass in the Authentication-Results header, assume DMARC will follow, and are surprised when aggregate reports show DMARC=fail. The trap is the difference between SPF AUTHENTICATION and SPF ALIGNMENT.

3.1 SPF authentication vs SPF alignment

SPF authentication (RFC 7208) asks: does the connecting client IP appear in the SPF record published at the envelope MAIL FROM domain? For an ESP-routed message the envelope domain is the ESP's bounce domain (e.g. bounces.sendgrid.net), the connecting IP is an ESP outbound IP, and the SPF record published at the ESP's bounce domain includes that IP. SPF authentication passes.

SPF alignment (RFC 7489 section 3.1.1) asks: does the SPF-authenticated domain match the header From: domain? For the same message the SPF-authenticated domain is bounces.sendgrid.net and the header From: is your-domain.com. The two domains do not share an organizational domain, so SPF alignment fails - even in DMARC's relaxed alignment mode (aspf=r), which only requires sharing the organizational domain after Public Suffix List trimming.

Result: SPF=pass + SPF-not-aligned + (DKIM=pass or DKIM=fail) -> DMARC=pass only if DKIM aligns, otherwise DMARC=fail.

3.2 Reading the trap in aggregate reports

In an RFC 7489 aggregate (RUA) report the trap surfaces as a record with policy_evaluated.dmarc=fail but auth_results.spf.result=pass AND auth_results.spf.domain set to the ESP's bounce domain (bounces.sendgrid.net, bounce.mailgun.org, amazonses.com) rather than your header From: domain. The DMARC Analyzer dashboard surfaces this via the source IP detail view, which shows the SPF-authenticated domain alongside the alignment verdict for every source IP. The fix is either configure custom-domain DKIM (primary) or configure a custom Return-Path / bounce subdomain (secondary, enables SPF alignment).

3.3 Custom Return-Path closes the SPF gap

Some ESPs (SendGrid, Mailgun, Amazon SES) let you configure a custom Return-Path / bounce subdomain: you publish a CNAME at em.your-domain.com (SendGrid), mailo.your-domain.com (Mailgun), or mail.your-domain.com (Amazon SES custom MAIL FROM) pointing to the ESP's bounce infrastructure. The ESP then sets the envelope MAIL FROM to your custom bounce subdomain instead of its own, so the SPF-authenticated domain becomes a subdomain of your organizational domain and SPF alignment passes natively. The SPF record at the bounce subdomain typically includes the ESP via include: mechanism. Section 6 below documents the per-ESP setup; section 4 documents the DKIM path which is the primary fix.

4. The DKIM alignment path (custom-domain CNAME-delegated DKIM)

DKIM alignment is the load-bearing DMARC pass mechanism for transactional email. The custom-domain DKIM pattern is universal across every ESP: you publish a CNAME (or TXT, in Postmark's case) at an ESP-specified selector under your-domain.com, the ESP signs every outbound message with d=your-domain.com s=<esp-selector>, and DKIM aligns with the header From:.

4.1 How CNAME-delegated DKIM works

  1. You request domain authentication at the ESP admin UI (typically Settings > Sender Authentication, Domain Settings, or Verified Identities depending on the ESP).
  2. The ESP generates a key pair internally and publishes the public key in DNS under its own control - at e.g. s1.domainkey.u12345.wl001.sendgrid.net (the actual hostname varies per ESP and per account).
  3. The ESP gives you a CNAME to publish at <esp-selector>._domainkey.your-domain.com pointing to its public-key hostname.
  4. You publish the CNAME at your DNS provider (Cloudflare, Route 53, Google Domains, your registrar's DNS panel, etc.).
  5. The ESP signs every outbound message with DKIM-Signature: v=1; a=rsa-sha256; d=your-domain.com; s=<esp-selector>; ....
  6. The receiver fetches the public key by looking up <esp-selector>._domainkey.your-domain.com, which CNAMEs to the ESP's hostname, which returns the actual TXT record with the public key.
  7. DKIM verifies successfully with d=your-domain.com, which aligns with the header From: domain, which makes DMARC pass.

4.2 Why CNAME delegation instead of a direct TXT record

Some ESPs (Postmark, Sendinblue / Brevo) publish the DKIM key as a direct TXT record you copy and paste into DNS. Others (SendGrid, Mailgun, Amazon SES) use CNAME delegation. CNAME delegation has one large operational advantage: the ESP can rotate the underlying key without your involvement. The CNAME target remains stable; the TXT record at the other end of the CNAME chain is what changes when the ESP rotates. Direct-TXT publication requires you to update DNS every time the ESP rotates, which is rarely automated and introduces a rotation-coordination overhead. For high-volume senders CNAME delegation is the operationally safer choice.

4.3 Why DKIM signatures survive forwarding (mostly)

DKIM signatures are computed over the message body (or a canonical form of it - see help_dkim_explained.php for the canonicalization deep dive) and over a selected subset of headers. As long as the body is not modified, the signature survives forwarding intact - so an ESP-signed message that gets forwarded to a personal address still passes DKIM verification at the forwarding hop. SPF on the other hand always breaks on forwarding because the connecting client IP at the forwarding hop is the forwarder's IP, not the original ESP's IP. This is a second reason DKIM is the load-bearing mechanism for transactional email: forwarded messages still pass DMARC via DKIM where they fail via SPF.

4.4 ARC seals preserve forwarded alignment

For mailing-list and aggressive-rewrite forwarders that DO modify the body (subject-line prefixes, footer injection), DKIM verification breaks at the forwarder. ARC (RFC 8617) - the Authenticated Received Chain - lets the forwarder vouch for the original DMARC verdict via an ARC-Seal + ARC-Authentication-Results + ARC-Message-Signature header trio. The receiver evaluates the ARC chain when the direct DMARC fails. Most major receivers (Gmail, Microsoft, Yahoo) honour valid ARC chains. See help_arc_explained.php for the ARC deep dive.

5. Per-ESP DKIM setup walkthroughs

Every ESP exposes the same fundamental custom-domain DKIM pattern through a different UI. The literal selector names and CNAME targets below are verified against each ESP's official documentation as of May 2026. Always confirm the exact values in the ESP admin UI before publishing - some ESPs assign per-account or per-region tokens that differ from the literals here.

5.1 Twilio SendGrid

  1. Sign in to SendGrid, open Settings > Sender Authentication and click Authenticate Your Domain.
  2. Select your DNS provider from the dropdown (Cloudflare, GoDaddy, Route 53, etc.) and enter your sending domain (e.g. example.com or the recommended dedicated subdomain transactional.example.com).
  3. SendGrid generates three CNAMEs:
    • em####.your-domain.com (custom Return-Path / bounce subdomain - the literal token em#### is account- specific).
    • s1._domainkey.your-domain.com (first DKIM selector).
    • s2._domainkey.your-domain.com (second DKIM selector - SendGrid rotates between s1 and s2 so both must always resolve).
  4. Publish all three CNAMEs at your DNS provider, then return to SendGrid and click Verify. SendGrid resolves the CNAMEs and marks the domain authenticated.
  5. Optionally enable Link Branding in the same UI to publish two more CNAMEs (url####.your-domain.com + 54321.your-domain.com) so click-tracking URLs route through your subdomain instead of sendgrid.net. Link Branding improves deliverability but is not strictly required for DMARC alignment.

Verify DKIM externally:

dig +short cname s1._domainkey.your-domain.com
# expect: s1.domainkey.u12345.wl001.sendgrid.net.
dig +short cname s2._domainkey.your-domain.com
# expect: s2.domainkey.u12345.wl001.sendgrid.net.
dig +short cname em1234.your-domain.com
# expect: u12345.wl001.sendgrid.net.

5.2 Mailgun

  1. Sign in to Mailgun, open Sending > Domain Settings, click Add New Domain, enter your sending domain (Mailgun strongly recommends a dedicated subdomain such as mg.example.com for SPF-record isolation), and choose your region (US or EU).
  2. Mailgun displays the DNS records to publish:
    • SPF: TXT v=spf1 include:mailgun.org ~all at the domain apex (or the subdomain if using one).
    • DKIM: CNAME mailo._domainkey.<domain> pointing to mailo.domainkey.u12345.eu.mailgun.org (newer accounts use mailo; older accounts use mta or pic - the Mailgun UI shows the literal selector).
    • MX (optional, only if you receive mail via Mailgun's inbound routing): 10 mxa.mailgun.org + 10 mxb.mailgun.org.
    • CNAME tracking (optional): email.<domain> pointing to mailgun.org.
  3. Publish all records, then click Verify DNS Settings - Mailgun resolves and marks the domain Active.
  4. If using a subdomain, publish DMARC at _dmarc.mg.example.com as well as (or instead of) the apex; the subdomain-policy sp= tag at the apex covers the subdomain when no explicit per-subdomain DMARC record exists.

Verify DKIM externally:

dig +short txt mailo._domainkey.your-domain.com
# expect: a long base64 public key starting with v=DKIM1; k=rsa; p=...

5.3 Amazon SES (Easy DKIM)

  1. Sign in to the AWS console, switch to the region you send from (us-east-1, eu-west-1, ap-south-1, etc. - SES is region-scoped). Open Amazon SES > Verified identities and click Create identity.
  2. Choose Domain, enter your sending domain, tick Use a custom MAIL FROM domain (recommended - enables SPF alignment), enter mail.your-domain.com (or any subdomain), and tick Easy DKIM (the default).
  3. SES generates three CNAMEs of the form <token>._domainkey.your-domain.com pointing to <token>.dkim.amazonses.com. The three tokens are random strings unique to your identity - do not edit them.
  4. For custom MAIL FROM, SES additionally requires:
    • MX 10 feedback-smtp.<region>.amazonses.com at mail.your-domain.com.
    • TXT v=spf1 include:amazonses.com ~all at mail.your-domain.com.
  5. Publish all records at your DNS provider. SES verifies within minutes (occasionally hours during AWS DNS-propagation slowdowns) and marks the identity Verified and DKIM Successful.
  6. Move your identity out of the SES sandbox via the Request Production Access form - in sandbox mode you can only send to other verified addresses, which is fine for testing but not for production.

Verify DKIM externally:

dig +short cname xxxxxxxxxxxxxxxxxxxx._domainkey.your-domain.com
# expect: xxxxxxxxxxxxxxxxxxxx.dkim.amazonses.com.
# (repeat for each of the 3 tokens shown in the SES console)

5.4 Postmark

  1. Sign in to Postmark, open your Server, click Sender Signatures > Add Domain or Add Signature, and enter your sending domain.
  2. Postmark displays the DNS records to publish. Unlike SendGrid / Mailgun / SES, Postmark publishes DKIM as a TXT record (NOT a CNAME) - you copy the full base64 public key from the Postmark UI and paste it into your DNS provider as the TXT value at <selector>._domainkey.your-domain.com. The selector is typically the literal date Postmark generated the key (e.g. 20240315) or a fixed pm selector for some accounts.
  3. SPF: publish TXT v=spf1 a mx include:spf.mtasv.net ~all at the domain apex.
  4. Return Path: Postmark handles bounces internally and does NOT support a custom Return-Path / bounce subdomain. SPF alignment therefore relies on the apex SPF record rather than on a subdomain CNAME - Postmark's envelope MAIL FROM is pm-bounces.<your-domain> which IS aligned natively because the bounce domain is at your-domain.
  5. Click Verify Signature - Postmark resolves the DKIM TXT record and marks the signature verified.

Verify DKIM externally:

dig +short txt 20240315._domainkey.your-domain.com
# expect: a long base64 public key starting with v=DKIM1; k=rsa; p=...

5.5 SparkPost

  1. Sign in to SparkPost, open Configuration > Sending Domains, click Add a Sending Domain, enter your sending domain.
  2. SparkPost displays a DKIM CNAME at scph0316._domainkey.your-domain.com pointing to scph0316.domainkey.sparkpostmail.com (the literal scph0316 is the SparkPost-default selector; enterprise accounts can specify custom selectors).
  3. SPF: SparkPost recommends TXT v=spf1 include:sparkpostmail.com ~all at the apex.
  4. Custom bounce domain (optional): publish a CNAME at bounce.your-domain.com pointing to sparkpostmail.com.
  5. Verify - SparkPost resolves DNS within minutes.

5.6 Mailjet

  1. Sign in to Mailjet, open Senders & Domains, click Add a sending domain, enter your sending domain.
  2. Mailjet displays:
    • SPF: TXT v=spf1 include:spf.mailjet.com ?all at the apex.
    • DKIM: a CNAME at mailjet._domainkey.your-domain.com pointing to mailjet.domainkey.mailjet.com.
  3. Click Check now. Mailjet verifies within minutes.

5.7 Sendinblue / Brevo

  1. Sign in to Brevo (formerly Sendinblue), open Senders & IPs > Domains, click Add a domain, enter your sending domain.
  2. Brevo displays:
    • Brevo code: a TXT record at the apex of the form brevo-code:<hash> for domain ownership verification.
    • SPF: TXT v=spf1 include:spf.brevo.com -all at the apex (Brevo recommends -all not ~all).
    • DKIM: a TXT record at mail._domainkey.your-domain.com containing the full base64 public key Brevo generated.
    • DMARC: a TXT record at _dmarc.your-domain.com - Brevo will recommend a starter policy of v=DMARC1; p=none; rua=mailto:dmarc@brevo.com but you should point rua= at YOUR mailbox so DMARC Analyzer ingests the reports, not Brevo.
  3. Publish all four records, then click Authenticate this domain.

5.8 Resend

  1. Sign in to Resend, open Domains, click Add Domain, enter your sending domain and choose the region (us-east-1 or eu-west-1).
  2. Resend displays:
    • SPF: TXT v=spf1 include:amazonses.com ~all at send.your-domain.com (Resend uses Amazon SES infrastructure under the hood, so the SPF include is amazonses.com).
    • DKIM: a CNAME at resend._domainkey.your-domain.com pointing to resend.amazonses.com (single selector, no rotation pair).
    • MX (for bounces): 10 feedback-smtp.<region>.amazonses.com at send.your-domain.com.
    • DMARC: a TXT record at _dmarc.send.your-domain.com with at minimum v=DMARC1; p=none; rua=mailto:dmarc-reports@your-domain.com.
  3. Publish all records and click Verify DNS Records.

5.9 MailerSend

  1. Sign in to MailerSend, open Domains, click Add Domain, enter your sending domain.
  2. MailerSend displays:
    • SPF: TXT v=spf1 include:_spf.mlsend.com ~all at the apex.
    • DKIM: two CNAMEs at mlsend._domainkey.your-domain.com and mlsend2._domainkey.your-domain.com pointing to MailerSend's key infrastructure.
    • Tracking (optional): CNAME at email.your-domain.com for click-tracking links.
    • Custom Return-Path: CNAME at mta.your-domain.com for SPF alignment via custom bounce domain.
  3. Click Verify Domain.

5.10 Mandrill (Mailchimp transactional)

  1. Sign in to Mailchimp, open the Transactional API / Mandrill product, then open Settings > Domains & Tracking.
  2. Mandrill uses the same domain authentication CNAMEs as the Mailchimp marketing product:
    • SPF: TXT v=spf1 include:spf.mandrillapp.com ?all at the apex.
    • DKIM: two CNAMEs at k1._domainkey.your-domain.com and k2._domainkey.your-domain.com pointing to dkim.mandrillapp.com and dkim2.mandrillapp.com.
    • Tracking (optional): CNAME at mail.your-domain.com.
  3. Click Verify Domain.

5.11 Other ESPs

Beyond the ten ESPs documented above, the same universal pattern applies. Look for the Domain Authentication / Sender Authentication / Verified Identities / Domains page in the ESP's admin UI, publish the CNAMEs (or TXT records) they generate, verify with dig +short cname <selector>._domainkey.your-domain.com, and proceed to DMARC publication. The 10 ESPs above cover roughly 90 percent of the transactional-email volume in production deployments; the remaining 10 percent (Pepipost / Netcore, Elastic Email, SocketLabs, SMTP2GO, Mailtrap, IBM Cloud Email Service, etc.) follow the same pattern with different selector literals.

6. Return-Path / custom bounce domain configuration (SPF alignment)

DKIM alignment is sufficient for DMARC to pass. SPF alignment is the bonus second path. For senders pursuing the Feb 2024 Google / Yahoo bulk-sender requirements, having BOTH SPF and DKIM aligned is the recommended configuration - Google explicitly mentions both in its Email sender guidelines.

6.1 The custom Return-Path mechanic

The ESP sets the envelope MAIL FROM (also called the bounce address or Return-Path) to a subdomain you control instead of one the ESP controls. You publish a CNAME at the subdomain pointing to the ESP's bounce-handling hostname:

  • SendGrid: em####.your-domain.com -> u12345.wl001.sendgrid.net (the em#### token is generated per-account).
  • Mailgun: the dedicated sending subdomain itself (mg.your-domain.com) acts as the bounce domain - no separate Return-Path CNAME needed.
  • Amazon SES: the custom MAIL FROM domain (mail.your-domain.com) with the MX + SPF records described in section 5.3.
  • SparkPost: bounce.your-domain.com -> sparkpostmail.com.
  • MailerSend: mta.your-domain.com as Custom Return-Path.

Postmark, Mailjet, Brevo, Resend, and Mandrill do not expose a separate custom Return-Path configuration - their default envelope MAIL FROM is either pre-aligned (Postmark via pm-bounces.your-domain.com) or relies on DKIM alignment alone.

6.2 Verifying SPF alignment after custom Return-Path setup

After publishing the custom Return-Path CNAME and waiting for DNS propagation, send a test message and inspect the Authentication-Results header at the receiver. The expected line shape is:

Authentication-Results: mx.google.com;
       dkim=pass header.i=@your-domain.com header.s=s1 header.b="...";
       spf=pass (google.com: domain of bounces+1234@em1234.your-domain.com
       designates 167.89.123.45 as permitted sender)
       smtp.mailfrom=bounces+1234@em1234.your-domain.com;
       dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=your-domain.com

The key indicators are smtp.mailfrom=...your-domain.com (envelope domain is a subdomain of your organizational domain) and dmarc=pass. The Email Header Analyzer on DMARC Analyzer parses this block and highlights alignment passes / failures via includes/EmailHeaderParser.php.

7. Subdomain segmentation strategy

The dedicated-subdomain pattern is the recommended architecture for transactional email at scale. Three motivations:

7.1 Reputation isolation

Receivers track sender reputation per organizational domain AND per subdomain. A transactional subdomain (transactional.example.com, mail.example.com, mg.example.com) accrues high-engagement reputation (password resets and 2FA codes get clicked, receipts get archived, and complaint rate stays low). Corporate mail (example.com apex via Workspace / M365) accrues normal-engagement reputation. Marketing mail (news.example.com via SendGrid Marketing or Mailchimp) accrues lower-engagement, higher-complaint reputation. Isolating each class behind its own subdomain means one campaign's bad day does not drag the transactional subdomain's reputation down - transactional deliverability stays stable.

7.2 Independent DMARC policy via np= / sp=

RFC 7489 defines sp= (subdomain-policy) which sets the DMARC policy for all subdomains of the organizational domain. RFC 9091 (formerly DMARCbis) introduces np= (non-existent-subdomain-policy) which sets policy for subdomains that do NOT have their own DMARC record. The tag deep dive covers each. Practical use:

  • At the apex, publish v=DMARC1; p=reject; sp=reject; np=reject; rua=mailto:dmarc@your-domain.com once corporate and transactional alignment are both clean.
  • During ESP onboarding, publish an explicit per-subdomain DMARC record at _dmarc.transactional.your-domain.com with p=none so the apex sp=reject does not block your in-flight ESP setup.
  • Once the transactional subdomain is clean, remove the subdomain-specific record and let the apex sp= tag take over - one canonical apex DMARC record covers every subdomain.

7.3 SPF 10-DNS-lookup limit relief

RFC 7208 section 4.6.4 caps SPF DNS lookups at 10 per evaluation. include: mechanisms each consume one lookup (plus the lookups in the included record). include:_spf.google.com is 3 lookups; include:sendgrid.net is 1-2; include:mailgun.org is 1; include:amazonses.com is 1. A sender with Workspace + SendGrid + Mailgun + SES at the apex hits 6-7 lookups before any custom infrastructure. Dedicated subdomains per ESP keep each SPF record under the limit:

; apex: corporate (Workspace) only
example.com.   TXT  "v=spf1 include:_spf.google.com ~all"

; transactional subdomain: SendGrid only
transactional.example.com.   TXT  "v=spf1 include:sendgrid.net ~all"

; marketing subdomain: Mailgun only
news.example.com.   TXT  "v=spf1 include:mailgun.org ~all"

7.4 Operational clarity

Each team owns a subdomain. The corporate security team owns the apex DMARC record; the application team owns the transactional subdomain; the marketing team owns the marketing subdomain. DNS-record changes are independent. Aggregate-report investigation is scoped to a subdomain. ESP onboarding does not require coordinating with security to ramp the apex.

8. Step-by-step rollout (SPF -> DKIM -> p=none -> ramp -> p=reject)

  1. Pick a sending domain (recommended: a dedicated subdomain such as transactional.your-domain.com or mail.your-domain.com).
  2. Configure ESP custom-domain DKIM per section 5 - publish the CNAME (or TXT) at the ESP-specified selector, verify with dig, click Verify in the ESP UI.
  3. Configure custom Return-Path / bounce subdomain per section 6 - optional but recommended for full alignment coverage.
  4. Publish SPF at the sending domain with the ESP's include mechanism. Verify with dig +short txt <domain>.
  5. Send a test message to a Gmail / Microsoft / Yahoo address you control. Open the message and view the Authentication-Results header (in Gmail: Show Original; in Outlook web: ... > View > View message source). Verify dkim=pass with header.i=@your-domain.com and ideally spf=pass with smtp.mailfrom=...your-domain.com (or any aligned envelope).
  6. Publish DMARC at p=none at _dmarc.your-domain.com (or at _dmarc.transactional.your-domain.com for a subdomain-only rollout). Minimum record: v=DMARC1; p=none; rua=mailto:dmarc-reports@your-domain.com.
  7. Wait 2-6 weeks and read aggregate (RUA) reports via DMARC Analyzer. Verify alignment pass rate is 95+ percent for the ESP's source IPs. Investigate any gaps via the source IP detail view + report detail view.
  8. Advance to p=quarantine for 4-12 weeks, with optional pct=25 through pct=100 ramp. Monitor for ANY new alignment failures from senders that newly appeared in aggregate reports.
  9. Advance to p=reject once quarantine has been clean for one full sender-rotation cycle (typically 4 weeks). Keep pct at 100 (the default).
  10. Maintain: read aggregate reports weekly per the monitoring guide. Investigate any new source-IP drift via the sender-inventory diff workflow documented there.

9. Bounce handling and feedback loops

9.1 Why bounce handling matters for DMARC

Bounce handling is operationally adjacent to DMARC because uncorrected bounces drive your complaint rate up, which drives your sender reputation down, which causes receivers to bulk-folder or delay your mail even when DMARC is correctly aligned. The Feb 2024 Google / Yahoo bulk-sender requirements set a complaint rate cap of 0.1 percent (one complaint per 1000 delivered messages). Exceeding that cap is a deliverability blocker.

9.2 ESP bounce-handling endpoints

Every major ESP exposes a webhook or HTTP API for bounce notifications. Subscribe your application to receive bounces and suppress addresses immediately after a hard bounce or spam complaint.

  • SendGrid: Settings > Mail Settings > Event Webhook with events bounce, dropped, spamreport, unsubscribe.
  • Mailgun: Sending > Webhooks with events permanent_fail, temporary_fail, complained, unsubscribed.
  • Amazon SES: configure an SNS topic per Configuration Set with event types Bounce, Complaint, Reject. The SES Feedback Forwarding option is OFF by default for production accounts - use SNS.
  • Postmark: Servers > <your-server> > Webhooks with events Bounce, SpamComplaint, SubscriptionChange.

9.3 Feedback loops (FBL)

Major receivers (Yahoo, AOL / Verizon Media, Microsoft via SNDS) expose a Feedback Loop that forwards spam complaints back to senders. ESPs subscribe to these on your behalf and surface complaints via the bounce-handling webhook. You do NOT need to register your domain with each receiver's FBL individually; that is the ESP's responsibility. Verify your ESP's FBL coverage in the ESP's documentation - SendGrid, Mailgun, SES, Postmark all automatically subscribe.

9.4 Suppression-list hygiene

Keep an internal suppression list of every address that has ever hard-bounced or complained. Re-attempting delivery to those addresses drives complaint rate up and reputation down. Every ESP also maintains a suppression list internally - SES, SendGrid, Mailgun, and Postmark all block sends to addresses on their internal list. Cross-check your application's list against the ESP's list periodically.

10. Dedicated IP vs shared IP authentication implications

10.1 Shared IP pools

By default every ESP places new accounts on a shared IP pool - your outbound mail leaves alongside hundreds or thousands of other ESP customers' mail from the same IP. Shared IP advantages: zero IP warmup required, the ESP handles reputation maintenance, you can ramp volume up and down freely. Shared IP disadvantages: your sender reputation is influenced by every other customer on the pool, so a high-complaint customer in the same pool can degrade your deliverability.

DMARC alignment works identically on shared and dedicated IPs - the IP does not change DKIM / SPF alignment. The Authentication-Results header will show the shared IP in the spf=pass verification, but that is irrelevant to alignment.

10.2 Dedicated IPs

Available on most ESPs (SendGrid Advanced, Mailgun Foundation, SES dedicated IPs, SparkPost Enterprise, Postmark Dedicated IP add-on) for an additional fee. Dedicated IPs must be warmed up - typically 30-60 days of progressively increasing volume so the receiver reputation engines learn your IP behaves well. Volume schedules vary; Mailgun and SES publish recommended warmup curves.

Dedicated IP advantages: your reputation is yours alone, large senders can hit higher receiver-side throughput limits. Disadvantages: warmup is mandatory; small senders (under 100k messages/month) cannot accumulate enough volume to maintain a reputation signal and end up worse off than on shared. Dedicated IP only makes sense above roughly 500k messages/month sustained.

10.3 Multiple dedicated IPs and IP rotation

Above 1M messages/month some senders run multiple dedicated IPs with weighted rotation - each IP carries a fraction of the load, receivers track each one independently, and isolation between transactional / marketing / notification traffic classes becomes practical. SendGrid, Mailgun, SES all support multi-IP pools with weighted routing.

DMARC alignment is unaffected by IP rotation. Each IP signs with the same DKIM key (because the key is per-domain, not per-IP) and the envelope MAIL FROM remains constant.

11. Multi-ESP estates

Many senders run multiple ESPs in parallel - SendGrid for marketing, Postmark for transactional, AWS SES for notification mail. The DMARC alignment surface scales linearly: each ESP needs its own custom-domain DKIM CNAMEs, each ESP signs with its own selector, and DMARC requires only ONE valid aligned signature per message to pass.

11.1 DKIM selector coexistence

Publishing s1._domainkey.your-domain.com + s2._domainkey.your-domain.com (SendGrid) + mailo._domainkey.your-domain.com (Mailgun) + <token>._domainkey.your-domain.com (Amazon SES, three of them) all at the same time is fine - each ESP signs messages with its own selector, the receiver looks up only the selector named in each message's DKIM-Signature header s= field, and unrelated selectors do not interfere.

11.2 SPF aggregation (or subdomain segmentation)

SPF is the bottleneck. Aggregating all ESPs into a single apex SPF record hits the 10-DNS-lookup limit fast. The recommended architecture is subdomain segmentation per section 7 - one ESP per subdomain, one SPF record per subdomain, each well under the limit.

If you must aggregate at the apex (e.g. because your stack uses a single From: domain across all sender categories), use an SPF flattening service that periodically resolves each include: mechanism into the underlying ip4 / ip6 ranges and republishes the resulting flat record. SPF flattening services include EasyDMARC SPF Flattening, dmarcian SPF Surveyor, Cloudflare Email Routing SPF Flattening, and self-hosted scripts. Note: flattening introduces fragility because the ESP's IP ranges change over time without notice, so the flattening service must run on a schedule (daily or weekly) and the operator must monitor it. The recommended approach is subdomain segmentation, not flattening.

11.3 Multi-ESP failover

For deliverability resilience some senders route the same message class through two ESPs - primary on SendGrid, failover on Amazon SES. DMARC alignment works the same way: both ESPs sign with custom-domain DKIM, both pass DMARC independently, and the receiver verifies whichever signature is present. The failover logic lives in your application or in an SMTP routing layer (Postal, Haraka, etc.); it is transparent to DMARC.

12. Common transactional-email DMARC mistakes

  1. Trusting SPF=pass without alignment. The most common cause of transactional-email DMARC failure. SPF passes for the ESP's bounce domain but does not align with your header From:. Custom-domain DKIM is the fix.
  2. Publishing only one of the SendGrid DKIM selectors. SendGrid rotates between s1._domainkey and s2._domainkey; if only one resolves, messages signed with the other selector fail DKIM verification. Always publish both.
  3. Forgetting to enable DKIM at the ESP sub-account level. Large SendGrid / Mailgun deployments use sub-accounts (one per business unit or per product line); DKIM is configured per sub-account, not globally. Publishing the parent account's CNAMEs does not authenticate the sub-account's outbound mail.
  4. Putting the DMARC record at the wrong subdomain. _dmarc.transactional.example.com covers From: foo@transactional.example.com only. From: foo@example.com from the SAME ESP requires DMARC at _dmarc.example.com with sp= or np= set appropriately - the per-subdomain record does not cover the apex.
  5. Ramping to p=reject before clean alignment. The 2-6 week p=none observation period is not optional. Skipping it means legitimate transactional mail bounces or quarantines at receivers, which users notice immediately (missing password resets are escalations).
  6. Forgetting the SPF 10-DNS-lookup limit when adding the second ESP. Workspace + SendGrid = ~5 lookups; adding Mailgun + SES pushes you past 10 and SPF breaks with permerror. Subdomain segmentation (section 7) avoids this.
  7. Sending from a domain that does not match the ESP-authenticated domain. If you authenticate example.com in SendGrid but send with From: alerts@notify.example.com, DKIM signs with d=example.com (in relaxed alignment that aligns OK with notify.example.com), but if SendGrid's config requires strict alignment or pins d=notify.example.com you need to authenticate the subdomain separately.
  8. Pointing rua= at the ESP's recommended fallback (dmarc@brevo.com, dmarc@mailgun.org, etc.). The ESP receives the reports instead of you. Always point rua= at your mailbox or your DMARC analytics platform (DMARC Analyzer, dmarcian, EasyDMARC, Valimail) so the reports flow to you.
  9. Leaving SPF at ?all or +all. The neutral (?all) and pass-all (+all) qualifiers tell receivers to ignore SPF authentication outcomes, which is the opposite of what you want. Always use ~all (softfail) or -all (hardfail). For DMARC-enforced domains -all is strictly correct - if your SPF includes are exhaustive, mail from any other IP should hardfail.
  10. Disregarding bounce notifications. Hard bounces and spam complaints not removed from your sender list drive complaint rate up and reputation down. Reputation degradation cascades into deliverability degradation even when DMARC is perfectly aligned. Subscribe to the ESP's bounce webhook per section 9.

13. Troubleshooting

13.1 ESP marks domain as Pending / Verification Failed

Most common cause: DNS propagation delay. CNAME records typically propagate in 1-15 minutes but some DNS providers cache for hours. Wait, then re-click Verify. If still failing, inspect the record value with dig and compare against the ESP's expected value byte-for-byte.

13.2 Aggregate reports show DKIM=fail at high rate

Three likely causes:

  1. The ESP's CNAME chain is broken. Confirm with dig +trace <selector>._domainkey.your-domain.com - the trace should resolve through the ESP's hostname to a TXT record containing v=DKIM1; k=rsa; p=.... If the CNAME chain terminates at a NXDOMAIN, the ESP rotated keys and the CNAME target is stale - re-authenticate the domain in the ESP UI.
  2. Sub-account DKIM not enabled (SendGrid / Mailgun multi-account deployments). Configure DKIM at the sub-account level in the ESP UI.
  3. Message body modified after signing. Mailing lists / forwarders / spam filters sometimes add footers or modify subjects. DKIM canonicalization (see help_dkim_explained.php) determines tolerance. ARC (section 4.4) recovers DMARC alignment through aggressive forwarders.

13.3 Aggregate reports show DMARC=fail with SPF=pass + DKIM=pass

This signals an alignment problem, not an authentication problem. Inspect the report's auth_results block:

  • If spf.domain is the ESP's bounce domain (bounces.sendgrid.net, bounce.mailgun.org, amazonses.com): SPF passed but did not align. Configure custom Return-Path (section 6) OR rely on DKIM alignment - check the next bullet.
  • If dkim.domain is the ESP's signing domain (sendgrid.net, mailgun.org, amazonses.com): DKIM passed but did not align - the ESP signed with its own d= instead of yours. Configure custom-domain DKIM (section 5) and verify the ESP UI shows the domain as authenticated.

13.4 New IP appears in aggregate reports with high volume

Either an ESP added IPs to its outbound pool (legitimate drift - update your sender inventory) or an unauthorized sender is spoofing your domain (file spoofing - investigate via the source IP detail view + report detail view). The monitoring guide documents the weekly sender-inventory-diff workflow that routes new IPs to one of the two outcomes.

13.5 ESP says DKIM is verified but receiver shows DKIM=fail

The ESP verifies the CNAME at publication time but does not continuously re-verify. If the CNAME target hostname later becomes unreachable (the ESP rotates infrastructure, your DNS provider has an outage, etc.), the receiver's DKIM lookup fails. Re-test the CNAME chain with dig +trace, contact ESP support if the target appears stale.

13.6 Diagnostic toolkit

  • Email Header Analyzer (header_analyzer.php) - parses Authentication-Results and DKIM-Signature headers via includes/EmailHeaderParser.php; identifies the signing domain, the selector, and the alignment verdict for any single message. The first tool to reach for when an end user reports a missing transactional email.
  • Domain Security Checker (domain_checker.php) - live DNS lookups for SPF, DKIM, DMARC, BIMI, MTA-STS, TLS-RPT, CAA via includes/DnsChecker.php; verifies every CNAME chain.
  • DNS Record Generator (dns_generator.php) - generates syntactically-correct DMARC, SPF, DKIM, BIMI, MTA-STS, TLS-RPT, CAA records when onboarding a new ESP.
  • Aggregate report drill-down (reporter_detail.php + source_ip_detail.php + reports_detail.php) - navigates RFC 7489 aggregate reports ingested via includes/DmarcParser.php.
  • Forensic / failure-sample drilldown when individual messages are spoofed - forensic reports ingested via includes/ForensicReportParser.php.
  • dig at the command line: dig +short cname <selector>._domainkey.your-domain.com, dig +short txt _dmarc.your-domain.com, dig +trace <selector>._domainkey.your-domain.com.

14. Frequently asked questions

How do I set up DMARC for SendGrid?
Five steps. (1) Sign in to SendGrid, open Settings > Sender Authentication, click Authenticate Your Domain, choose your DNS provider, and enter your sending domain (e.g. example.com or transactional.example.com). (2) SendGrid generates a set of CNAMEs typically rooted at em.<your-domain>, s1._domainkey.<your-domain>, and s2._domainkey.<your-domain>. Publish all three CNAMEs at your DNS provider (Cloudflare, Route 53, Google Domains, etc.) - the em.<your-domain> CNAME is the custom Return-Path for SPF alignment, the s1 and s2 CNAMEs are the rotating DKIM key pair for DKIM alignment. (3) Return to SendGrid and click Verify; SendGrid resolves the CNAMEs and marks the domain authenticated. (4) Publish DMARC at _dmarc.<your-domain> with v=DMARC1; p=none; rua=mailto:dmarc-reports@<your-domain> to start collecting aggregate reports. (5) After 2-6 weeks of clean reports advance p=quarantine then p=reject. SendGrid signs every message with s=s1 or s=s2 alternating, so both selectors must resolve at all times - never delete one without rotating to the new pair first.
How do I set up DMARC for Mailgun?
Five steps. (1) Sign in to Mailgun, open Sending > Domain Settings, click Add New Domain, enter your sending domain (e.g. mg.example.com or transactional.example.com - Mailgun strongly recommends a dedicated subdomain), and choose your region (US or EU). (2) Mailgun displays the DNS records you must publish: a TXT record at the domain apex for SPF (v=spf1 include:mailgun.org ~all - or include:mailgun.org and your own ip4: ranges if you also send from your own infrastructure), a CNAME at mailo._domainkey.<your-domain> (newer DKIM selector; older Mailgun accounts use mta._domainkey or pic._domainkey - check the Domain Settings page for the literal name), and optionally MX records if you also receive mail via Mailgun. (3) Publish all records at your DNS provider, then click Verify DNS Settings - Mailgun resolves the records and marks the domain Active. (4) Publish DMARC at _dmarc.<your-domain> (or _dmarc.mg.<your-domain> for the subdomain) with v=DMARC1; p=none; rua=mailto:dmarc-reports@<your-domain>. (5) After 2-6 weeks of clean reports advance to p=quarantine then p=reject.
How does Amazon SES Easy DKIM work for DMARC?
Amazon SES Easy DKIM publishes a 2048-bit DKIM key automatically when you verify a sending identity (a domain or a subdomain). Five steps. (1) Sign in to the AWS console, open SES > Verified identities, click Create identity, choose Domain, enter your sending domain, and tick Use a custom MAIL FROM domain (recommended). (2) Tick Easy DKIM (the default) - SES generates three CNAMEs of the form <token>._domainkey.<your-domain> pointing to <token>.dkim.amazonses.com (the tokens are random strings unique to your identity, do not edit them). The custom MAIL FROM option requires an additional MX record (10 feedback-smtp.<region>.amazonses.com) and a TXT SPF include (v=spf1 include:amazonses.com ~all) at your chosen MAIL FROM subdomain. (3) Publish all 3 DKIM CNAMEs + MAIL FROM records at your DNS provider, then wait for AWS to verify (typically minutes, occasionally hours). (4) Publish DMARC at _dmarc.<your-domain> with v=DMARC1; p=none; rua=mailto:dmarc-reports@<your-domain>. (5) Advance to enforcement after clean reports. Easy DKIM auto-rotates keys every quarter; the CNAMEs do not change - they always point to SES, which controls the underlying private key behind the scenes.
How do I set up DMARC for Postmark?
Postmark uses Sender Signatures (per-address) and per-domain DKIM. Four steps. (1) Sign in to Postmark, open the Server you send from, click Sender Signatures > Add Domain or Add Signature, enter your sending domain (e.g. example.com or transactional.example.com). (2) Postmark displays the DKIM TXT record - a long base64 public key at <selector>._domainkey.<your-domain> where <selector> is typically the literal date Postmark generated the key (e.g. 20240101 or pm._domainkey). Publish the TXT record at your DNS provider exactly as shown (Postmark publishes the actual public key as a TXT value, NOT a CNAME - this is a deliberate design choice for verification simplicity). Also publish a TXT SPF include at the domain apex: v=spf1 a mx include:spf.mtasv.net ~all. (3) Click Verify Domain in Postmark - it resolves the DKIM TXT record and marks the signature verified. (4) Publish DMARC at _dmarc.<your-domain> with v=DMARC1; p=none; rua=mailto:dmarc-reports@<your-domain>, then advance to enforcement after clean reports.
Why does my transactional email pass SPF but fail DMARC?
Almost always because SPF passes for the ESP infrastructure but the envelope MAIL FROM domain (5321.From) does not align with your visible header From: (5322.From). ESPs typically rewrite the envelope MAIL FROM to an ESP-controlled bounce domain (bounces.sendgrid.net for SendGrid, bounce.mailgun.org for Mailgun, <region>.amazonses.com for Amazon SES) so the ESP can handle delivery failures. SPF checks that bounce domain against the ESPs SPF record, which passes - but DMARC requires alignment of the SPF-authenticated domain with the header From: domain, which fails because the bounce domain does not match your-domain.com. Fix: configure custom-domain DKIM at the ESP (CNAMEs at <selector>._domainkey.<your-domain> pointing to the ESPs key infrastructure) so DMARC aligns via DKIM regardless of envelope rewriting. Optionally also configure a custom Return-Path / bounce subdomain (em.<your-domain> CNAME to the ESPs bounce hostname) so SPF aligns too, but DKIM alignment is the load-bearing mechanism for transactional email.
Should I use a dedicated subdomain for transactional email?
Yes - the dedicated-subdomain pattern (e.g. transactional.example.com, mail.example.com, mg.example.com) is the recommended architecture for transactional email at scale. Three benefits. (1) Reputation isolation: transactional traffic (high engagement, low complaint rate) builds a distinct sender reputation from corporate mail (employees emailing externally, often with attachments) and marketing mail (lower engagement, higher complaint rate). Receivers track reputation per subdomain, so isolating each class of mail prevents one bad day from degrading the others. (2) Independent DMARC policy via the np= / sp= tags: the organizational domain can ramp p=reject while a subdomain remains at p=none during ESP onboarding. (3) Operational clarity: every team can verify alignment for their subdomain without coordinating with the security team owning the apex. Cost: requires the ESP to authenticate the subdomain (one set of CNAMEs per subdomain) and your DNS provider to publish per-subdomain records. Tradeoff is worth it above ~5000 transactional messages/day or whenever the Feb 2024 Gmail / Yahoo bulk-sender thresholds apply.
How do I handle DMARC when I use multiple ESPs at the same time?
Each ESP needs its own custom-domain DKIM CNAMEs published in your DNS, all under distinct selectors. SendGrid uses s1._domainkey and s2._domainkey; Mailgun uses mailo._domainkey; Amazon SES uses three random tokens; Postmark uses a date-named selector. Publishing all four sets of CNAMEs simultaneously is fine - each ESP signs messages with its own selector, and DMARC requires only ONE valid DKIM signature aligned with the header From: domain to pass. The receiver looks up only the selector named in the DKIM-Signature header s= field of each message, so unrelated selectors do not interfere. For SPF: include all ESPs in a single SPF record at the apex, but watch the 10-DNS-lookup limit (RFC 7208 section 4.6.4) - SendGrid + Mailgun + Amazon SES + your own MTA already consumes 4-6 lookups before counting redirects. Use a dedicated subdomain per ESP (transactional.example.com on SendGrid, marketing.example.com on Mailgun, etc.) to keep each SPF record under the limit and isolate reputation.
Do I need DMARC at p=reject if I only send transactional email?
Yes, especially for transactional email. Three reasons. (1) Transactional messages (password resets, 2FA codes, magic links, payment receipts) are high-value spoofing targets because they trigger user action - a forged password-reset email lands in the same inbox as a legitimate one, and only DMARC enforcement blocks the forgery at receiver level. (2) The Feb 2024 Google / Yahoo bulk-sender requirements explicitly mandate DMARC at p=quarantine or stricter for senders above 5000 messages/day to Gmail / Yahoo Mail; transactional senders routinely exceed this threshold. (3) At p=none receivers DELIVER spoofed messages to the inbox - DMARC at p=none gives you reporting visibility but provides zero blocking. Operators should treat p=reject as the production-ready end state and treat p=none as a temporary alignment-debug stop on the rollout path. The DMARC Analyzer dashboard walks the operator through the ramp via the rollout guide help_dmarc_policy_rollout.php and the troubleshooting loop help_dmarc_troubleshooting.php.

16. Start verifying your transactional email alignment now

DMARC Analyzer ingests aggregate (rua) reports via includes/DmarcParser.php and surfaces every per-source-IP alignment outcome on the dashboard (index.php). The per-source-IP drilldown (source_ip_detail.php) shows which ESPs are aligning cleanly and which are not; the per-reporter drilldown (reporter_detail.php) shows which receivers (Google, Microsoft, Yahoo, La Poste, Mail.ru) are receiving your authenticated transactional mail. The header_analyzer.php tool (built on includes/EmailHeaderParser.php) diagnoses single-message alignment when a user reports a missing password reset. The domain_checker.php tool (built on includes/DnsChecker.php) live-resolves every CNAME chain so you can confirm a new ESP's DKIM setup before sending the first message. Forensic (ruf) failure samples land via upload.php through includes/ForensicReportParser.php for spoofing investigation.

Check my domain configuration Sign up — Free plan