DMARC Engine
Home/Documentation/Delegating your DNS with CNAMEs
Documentation

Delegating your DNS with CNAMEs

How CNAME delegation works in DMARC Engine: the exact records for DMARC, SPF, DKIM, MTA-STS and BIMI, host-by-host setup, and how to verify propagation.

22 May 2026 · The DMARC Engine Team · 30 min read

Why delegate your DNS to DMARC Engine

Email authentication is made of small, fiddly DNS records - DMARC, SPF, DKIM, MTA-STS and BIMI - and every one of them needs to stay correct and current. SPF has to be re-flattened every time a sending tool changes its IP ranges. DKIM keys should rotate periodically. MTA-STS policies need a certificate and a web server behind them. Get any of this wrong and mail starts bouncing or landing in spam.

DMARC Engine solves this with hosted delegation: instead of you maintaining the raw record forever, you publish a single CNAME in your own DNS that points at a record we manage on our infrastructure. We keep the underlying content correct - flattening SPF as your senders change, rotating DKIM keys, renewing the MTA-STS certificate - and you never have to touch your DNS zone again for that record.

This guide is the deep-reference for that delegation model. It covers:

  • The exact CNAME (or TXT) record to publish for each of the five services
  • Step-by-step instructions for the most common DNS hosts
  • CNAME-at-apex limitations and how we work around them
  • TTL and propagation behaviour, and how to confirm a delegation has resolved
  • The self-managed alternative, for the rare case you'd rather publish records yourself

If you haven't added your domain to DMARC Engine yet, start at app.dmarcengine.com/domains - every record below assumes the domain already exists there, because the CNAME target is generated per-domain (we call it your hosting slug).

Note Every hosted record in this guide follows the same shape: <something>.<domain> → CNAME → <something>.<slug>.dmarcengine.com. Once you've set up one service this way, the rest follow the identical pattern.

---

How hosted delegation works

When you add a domain in DMARC Engine, we generate a unique hosting slug for it (visible on the domain's page in the app) and a rua token used for DMARC aggregate reports. Every hosted CNAME target below is built from those two values.

The mental model:

  1. You publish a CNAME (or, for SPF, a TXT with an include:) in your own authoritative DNS.
  2. DNS resolvers follow that CNAME to a record served on dmarcengine.com.
  3. We keep the content behind that record current - automatically - as your policy, senders, DKIM keys, or certificate change.
  4. You see live status, coverage, and any drift in app.dmarcengine.com/domains, and can drill into each service from its own builder page.

The advantage over publishing the raw value yourself is simple: the record content can change without you having to touch your DNS zone again. This matters most for SPF (which needs re-flattening whenever a sender's IP ranges change) and DKIM (which should be rotated periodically) and MTA-STS (which needs a maintained certificate).

The five services at a glance

ServiceWhat you publish in your DNSWhat we serve
DMARCCNAME at _dmarc.<domain>Your DMARC policy + aggregate report address
SPFTXT with include:<slug>.spf.dmarcengine.comAn auto-flattened SPF chain under 10 lookups
DKIMCNAME at <selector>._domainkey.<domain>Your DKIM public key, with rotation support
MTA-STSCNAME at mta-sts.<domain> + CNAME at _mta-sts.<domain>A signed MTA-STS policy over HTTPS + the STSv1 id TXT
TLS-RPTCNAME at _smtp._tls.<domain>Your TLS reporting address
BIMICNAME at <selector>._bimi.<domain>Your BIMI SVG logo record (and VMC, if you have one)

Each service also has a dedicated builder in the app where you can review, test, and copy the exact record for your domain: /dmarc, /spf, /dkim, /mta-sts, and /bimi.

---

DMARC: the delegated record

DMARC is the policy record that tells receiving mail servers what to do with messages that fail authentication, and where to send aggregate (RUA) and forensic (RUF) reports.

The hosted record

Publish this CNAME in your DNS, replacing <slug> with the hosting slug shown on your domain's page:

_dmarc.example.com.    CNAME    <slug>._dmarc.dmarcengine.com.

Behind that CNAME we serve your actual DMARC policy, something like:

v=DMARC1; p=quarantine; rua=mailto:r-<token>@reports.dmarcengine.com; ruf=mailto:r-<token>@reports.dmarcengine.com; fo=1

You never publish that policy text yourself - it lives behind the CNAME, and you manage the policy strength (nonequarantinereject), pct, and reporting options entirely from app.dmarcengine.com/dmarc. Every DMARC aggregate report your domain generates is routed to r-<token>@reports.dmarcengine.com and parsed automatically into /analytics and /reports - no mailbox to manage, no XML to unzip.

Tip If you're new to DMARC policy strength and ramp-up, read the companion guide Understanding DMARC policies: none, quarantine and reject before you move past p=none.

Step by step

  1. Sign in and open app.dmarcengine.com/domains, then select your domain (or add it first).
  2. Open the DMARC tab, or go straight to /dmarc.
  3. Copy the CNAME record shown - it already has your slug filled in.
  4. Log in to your DNS host and create a CNAME record with host _dmarc pointing to the target shown.
  5. Save, wait for propagation (see TTL and propagation), then click Verify on the DMARC page, or use /lookup to query _dmarc.example.com directly.
  6. Once verified, set your desired policy (none to start) from the same page - changing it does not require any further DNS edits, because the policy lives behind the CNAME.
Warning Do not leave a pre-existing raw _dmarc TXT record in place alongside the CNAME. A domain can only have one type of record at a given name - a CNAME cannot coexist with a TXT at _dmarc.example.com. Delete any old DMARC TXT record before adding the CNAME.

---

SPF: the delegated record

SPF authorises which servers may send mail as your domain. It's a plain TXT record, but it has a hard 10 DNS-lookup limit - every include:, a, mx, ptr, and nested include counts. Once you use two or three sending tools (Google Workspace, Microsoft 365, a marketing platform, a helpdesk, a CRM) it's very easy to blow past 10 lookups, at which point SPF fails outright for everyone, even legitimate senders.

The hosted record

Unlike DMARC, DKIM, MTA-STS and BIMI, SPF cannot be a CNAME - a domain's root TXT record can't itself be a CNAME if you also need MX or other records at the apex (see CNAME-at-apex caveats). So for SPF you publish a normal TXT record that includes our flattened chain:

example.com.    TXT    "v=spf1 include:<slug>.spf.dmarcengine.com ~all"

Behind <slug>.spf.dmarcengine.com we maintain a fully flattened SPF chain: every sender you've added in app.dmarcengine.com/spf is resolved down to raw IP ranges and packed into as few lookups as possible, split across multiple include records if needed to stay under the limit. When a vendor (say, your email marketing platform) changes their sending IPs, we re-flatten automatically - you don't lift a finger.

Step by step

  1. Open app.dmarcengine.com/spf.
  2. Add every service that sends mail as your domain (Google Workspace, Microsoft 365, your ESP, helpdesk, CRM, etc.) - the builder has common providers pre-filled.
  3. Copy the generated TXT record; it will look like the example above with your slug in it.
  4. In your DNS host, create (or edit) the TXT record at the root of your domain (host name @ or blank, depending on host) with that exact value.
  5. Remove any other v=spf1 TXT records at the same name - a domain must have only one SPF record. Multiple SPF TXT records is itself a permanent failure condition per RFC 7208.
  6. Save, allow propagation, then click Verify on the SPF page, or run a check via /lookup or the free SPF checker.
Note The ~all (softfail) at the end is a sensible default while you're onboarding. Once you're confident every legitimate sender is covered, you can tighten it to -all (hardfail) from the SPF builder - again, no DNS edit required beyond what you already published, since -all vs ~all is part of the include chain we serve, not something you retype yourself unless you set the qualifier locally.
Warning If you add an SPF include manually alongside ours (say, a leftover include:_spf.google.com) you re-introduce the lookup-limit problem you're trying to solve. Let the DMARC Engine SPF builder be the single source of truth for every sender; add new senders there, not directly in DNS.

For the underlying mechanics, see How SPF flattening works.

---

DKIM: the delegated record

DKIM cryptographically signs outgoing mail with a private key; the public key is published in DNS at a selector-specific name so receivers can verify the signature.

The hosted record

<selector>._domainkey.example.com.    CNAME    <selector>.<slug>._domainkey.dmarcengine.com.

Replace <selector> with the selector your sending platform (or DMARC Engine itself, if you're using our outbound signing) assigns - commonly something like s1, dmarcengine1, or a vendor-specific string like google or selector1. You'll have one CNAME per active selector; most domains run one or two at a time, plus a spare during rotation.

Behind the CNAME, we serve the actual public key record:

v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC...

Because the key lives behind our CNAME, key rotation never touches your DNS. When you rotate from app.dmarcengine.com/dkim, we update the served record instantly and the CNAME keeps pointing at the same place.

Step by step

  1. Open app.dmarcengine.com/dkim and generate or import a selector for your domain.
  2. Note the exact selector name and the CNAME target shown.
  3. In your DNS host, create a CNAME record with host <selector>._domainkey pointing to the target.
  4. If you have multiple sending platforms each with their own selector (e.g. Microsoft 365's selector1/selector2, plus your ESP's own selector), repeat for each - you can host as many selectors as you have active senders.
  5. Save, wait for propagation, then click Verify on the DKIM page or check via /lookup.
  6. Confirm your sending platform is actually configured to sign with that selector's private key (this half lives on the sending side, in whatever platform originates the mail - DMARC Engine only publishes and serves the DNS side unless you're using our outbound relay).
Note DKIM selectors are just labels - they don't need to match anything else in your setup. If a sending platform tells you "publish this DKIM CNAME with selector xyz123", use that exact selector name as the left-hand host in the record above.
Tip Keep a spare, unused selector staged and verified before you need it. That way, rotating keys is a same-day operation from the DKIM builder rather than a DNS emergency.

---

MTA-STS and TLS-RPT: the delegated records

MTA-STS (Mail Transfer Agent Strict Transport Security) forces inbound mail to your domain to arrive over an authenticated TLS connection, closing the door on downgrade and interception attacks. It needs two DNS records plus a policy file served over HTTPS. TLS-RPT is the companion reporting mechanism that tells you when a sending server couldn't establish a secure connection.

The hosted records

1. The MTA-STS host CNAME - this is what makes https://mta-sts.example.com/.well-known/mta-sts.txt resolve to our servers, which hold your SSL certificate and serve the current policy:

mta-sts.example.com.    CNAME    mta-sts.dmarcengine.com.

2. The MTA-STS policy-id TXT, delegated the same way as everything else:

_mta-sts.example.com.    CNAME    <slug>._mta-sts.dmarcengine.com.

Behind that second CNAME we serve the STSv1 id record, e.g. v=STSv1; id=20260703120000Z - the id changes automatically whenever your policy changes, which is exactly the kind of upkeep this delegation model exists to remove from your plate.

3. TLS-RPT, for receiving reports about failed TLS connections to your mail servers:

_smtp._tls.example.com.    CNAME    <slug>._smtp._tls.dmarcengine.com.

Step by step

  1. Open app.dmarcengine.com/mta-sts.
  2. Confirm your MX hosts are listed correctly in the policy builder (MTA-STS policy mode should match how strict you want enforcement - start with testing if you're new to this).
  3. Add three CNAME records in your DNS host:
  4. - mta-stsmta-sts.dmarcengine.com
  5. - _mta-sts<slug>._mta-sts.dmarcengine.com
  6. - _smtp._tls<slug>._smtp._tls.dmarcengine.com
  7. Save and allow propagation.
  8. Click Verify on the MTA-STS page - this checks both the DNS records and that the policy is actually being served correctly over HTTPS at https://mta-sts.example.com/.well-known/mta-sts.txt.
  9. Once the testing policy is confirmed live and stable for a few days, switch mode to enforce from the same builder page.
Note The HTTPS certificate for mta-sts.example.com is provisioned and renewed automatically as part of hosted delegation - you do not need to buy or install a certificate yourself. This is one of the biggest reasons to delegate rather than self-host MTA-STS.
Warning MTA-STS policy mode enforce will cause sending servers to refuse delivery to your domain over an insecure or misconfigured connection. Only move to enforce once you've confirmed every MX host you list actually offers valid TLS - verify thoroughly in testing mode first.

For more detail on rollout strategy, see MTA-STS and TLS-RPT: locking down inbound mail.

---

BIMI: the delegated record

BIMI (Brand Indicators for Message Identification) displays your logo next to authenticated mail in supporting inboxes (Gmail, Yahoo, Apple Mail and others). It's the visual payoff of a strong DMARC posture - most providers require you to be at p=quarantine or p=reject with sufficient enforcement before they'll show the logo.

The hosted record

<selector>._bimi.example.com.    CNAME    <selector>.<slug>._bimi.dmarcengine.com.

The BIMI selector is almost always default unless you have a specific reason to use another. Behind the CNAME we serve your logo record:

v=BIMI1; l=https://dmarcengine.com/bimi-assets/<slug>/logo.svg; a=https://dmarcengine.com/bimi-assets/<slug>/vmc.pem

We host the SVG (in the required square, tiny-PS profile) and, if you have one, the Verified Mark Certificate (VMC) that unlocks BIMI display in Gmail. Uploading a new logo or VMC from the BIMI builder updates the served record instantly - again, no DNS change required after the initial CNAME is in place.

Step by step

  1. Open app.dmarcengine.com/bimi and upload your logo - we handle conversion to the compliant square SVG raster automatically.
  2. Confirm your DMARC record is enforcing at p=quarantine (pct=100) or p=reject - most mailbox providers won't display a BIMI logo below that bar.
  3. (Optional but recommended for Gmail) Upload a VMC if you have one issued by a certificate authority such as DigiCert or Entrust.
  4. Copy the CNAME shown and add it to your DNS host: host default._bimi (or your chosen selector) pointing at the target.
  5. Save, allow propagation, then click Verify on the BIMI page, or check via /lookup.
  6. Send yourself a test message through a BIMI-supporting mailbox and check the logo appears - display can lag behind DNS by a day or two even after everything verifies correctly, because mailbox providers cache BIMI eligibility.
Tip BIMI is the last step, not the first. If you haven't ramped your DMARC policy up yet, start with the DMARC policy guide and come back to BIMI once you're enforcing.

---

Setting up CNAMEs at your DNS host

The record you create is identical across hosts - a CNAME with a given host/name pointing at a given target. What differs is where the "Add record" button lives. Below are the popular hosts.

Cloudflare

  1. Log in to the Cloudflare dashboard and select your domain (zone).
  2. Go to DNSRecords.
  3. Click Add record.
  4. Set Type to CNAME.
  5. In Name, enter just the subdomain part (e.g. _dmarc, default._bimi, s1._domainkey) - Cloudflare appends your domain automatically.
  6. In Target, paste the full hosted target (e.g. <slug>._dmarc.dmarcengine.com).
  7. Important: set the orange-cloud Proxy status to DNS only (grey cloud) for every DMARC Engine CNAME. Proxying these records through Cloudflare's network breaks resolution for mail-authentication lookups.
  8. Set TTL to Auto (fine for CNAMEs) and click Save.
Warning Cloudflare users hit this one constantly: leaving a record proxied (orange cloud) means mail servers resolve to a Cloudflare anycast IP instead of following the CNAME to us - DMARC, SPF-related lookups, DKIM, MTA-STS and BIMI records will all silently fail to verify. Always set these to DNS only.

GoDaddy

  1. Log in and go to My Products → find the domain → DNS.
  2. Under Records, click Add New Record.
  3. Type: CNAME.
  4. Name/Host: enter the subdomain (e.g. _dmarc), not the full domain.
  5. Value: paste the hosted target (GoDaddy usually wants no trailing dot - leave it off if the field rejects one).
  6. TTL: leave default (1 Hour) or set to a lower value while you're actively testing.
  7. Click Save.
Note GoDaddy sometimes flags underscore-prefixed host names (_dmarc, _mta-sts) as invalid in older interface versions. If you hit that, use GoDaddy's newer DNS management UI, or contact their support - underscore records are valid DNS and required by these standards.

Namecheap

  1. Sign in, go to Domain List, click Manage next to the domain.
  2. Open the Advanced DNS tab.
  3. Click Add New Record.
  4. Type: CNAME Record.
  5. Host: the subdomain only (e.g. s1._domainkey).
  6. Value: the hosted target, with a trailing dot is fine (Namecheap normalises it).
  7. TTL: Automatic is fine.
  8. Click the green checkmark to save.
Warning If Namecheap's default parking-page redirect or "URL Redirect Record" is still active on your domain, remove it before adding authentication records - a redirect record at the root can conflict with the SPF TXT record you need at @.

AWS Route 53

  1. Open the Route 53 console → Hosted zones → select your zone.
  2. Click Create record.
  3. Record name: the subdomain (e.g. _dmarc).
  4. Record type: CNAME.
  5. Value: the hosted target, exactly as shown (Route 53 requires a fully-qualified target; a trailing dot is optional but harmless).
  6. TTL (seconds): 300 is a reasonable value while testing; raise to 3600 once stable.
  7. Routing policy: leave as Simple routing.
  8. Click Create records.
Tip Route 53 lets you batch-import records via a JSON/text change-batch through the CLI (aws route53 change-resource-record-sets). If you're delegating several domains at once, this is faster than clicking through the console for each record - see the DNS record cookbook for copy-paste JSON examples.

Google Domains / Squarespace Domains

Google Domains' DNS product moved to Squarespace; the steps below apply to the current Squarespace-operated interface (and legacy Google Domains where it's still active).

  1. Log in to your domain's DNS settings (Squarespace: Domains → select domain → DNS Settings).
  2. Under Custom records, click Add record.
  3. Type: CNAME.
  4. Host name: the subdomain (e.g. mta-sts).
  5. Data: the hosted target, with trailing dot.
  6. TTL: 1 hour default is fine.
  7. Click the checkmark / Save.
Note Squarespace's interface only allows one record per exact host name - if you already have a CNAME at that name (e.g. a leftover DKIM setup from a previous provider), you must delete or edit the existing one rather than add a duplicate.

Microsoft 365 (admin centre DNS management)

If your domain's DNS is managed inside the Microsoft 365 admin centre rather than at a registrar:

  1. Go to the Microsoft 365 admin centreSettingsDomains.
  2. Select your domain, then DNS records.
  3. Click Add record (sometimes under Manage DNS recordsAdd).
  4. Type: CNAME.
  5. Alias/Host name: the subdomain (e.g. _dmarc).
  6. Points to address / Target: the hosted target, with trailing dot.
  7. TTL: default is fine.
  8. Save.
Warning If Microsoft 365 manages your MX and it also auto-manages a DKIM CNAME pair for its own signing (selector1._domainkey / selector2._domainkey pointing at *.onmicrosoft.com), do not remove those - they're for Microsoft 365's own DKIM signing of your outbound mail through their servers. Add your DMARC Engine DKIM selector as an additional record with a different selector name; don't overwrite Microsoft's.

IONOS (1&1)

  1. Log in to the IONOS control panel, go to Domains & SSL → select the domain → DNS.
  2. Click Add record.
  3. Type: CNAME.
  4. Host name: the subdomain (e.g. default._bimi).
  5. Points to: the hosted target.
  6. TTL: default.
  7. Click Save.
Note IONOS occasionally requires the host-name field to include the domain automatically (i.e. it will show _dmarc.example.com once saved even though you typed only _dmarc) - this is cosmetic and doesn't need a trailing dot from you.

Quick host-by-host summary

DNS hostMenu pathHost/Name field takesTrailing dot needed?
CloudflareDNS → Records → Add recordSubdomain onlyNo; must be DNS only (grey cloud)
GoDaddyMy Products → DNS → Add New RecordSubdomain onlyNo
NamecheapDomain List → Manage → Advanced DNSSubdomain onlyOptional
AWS Route 53Hosted zones → Create recordSubdomain onlyOptional
Squarespace/Google DomainsDNS Settings → Custom recordsSubdomain onlyUsually yes
Microsoft 365 admin centreSettings → Domains → DNS recordsSubdomain onlyUsually yes
IONOSDomains & SSL → DNS → Add recordSubdomain onlyNo

If your host isn't listed, the pattern is universal: create a CNAME record, put only the subdomain portion in the host/name field (never the full domain - most interfaces append it for you), and paste the target exactly as shown on the relevant DMARC Engine builder page.

---

CNAME-at-apex caveats

A CNAME record cannot coexist with any other record type at the same name, and - per the DNS standard - a domain's apex (the bare root, e.g. example.com with no subdomain) typically already needs an A/AAAA record for the website and an MX record for mail. That's why:

  • DMARC, DKIM, MTA-STS's two records, TLS-RPT, and BIMI are all published at subdomains (_dmarc., <selector>._domainkey., mta-sts., _mta-sts., _smtp._tls., <selector>._bimi.) - never at the apex - so a CNAME is always valid there.
  • SPF is the one exception that genuinely must live at the apex (example.com itself), which is precisely why it can't be a CNAME - it has to be a TXT record living alongside your existing A/MX records at that same name. That's why the hosted SPF delegation uses an include: inside a TXT you publish, rather than a CNAME.
Note Some registrars advertise "CNAME flattening" or "ALIAS" records that let you point the apex itself at a CNAME-like target for website hosting. That feature is unrelated to SPF - SPF's TXT record at the apex is unaffected by, and doesn't need, ALIAS/flattening support.
Warning Never attempt to replace your apex A or MX records with a CNAME to work around this - it's invalid DNS and most authoritative nameservers will reject the zone or silently break mail and web delivery. The subdomain-based design above exists specifically so you never need to.

---

TTL and propagation: what to expect

TTL (Time To Live) controls how long resolvers cache a DNS record before re-checking your authoritative nameservers. It's specified in seconds.

  • Typical default TTLs range from 300 seconds (5 minutes) at hosts like Route 53 or Cloudflare, up to 3,600 seconds (1 hour) or even 86,400 seconds (24 hours) at some registrar-default zones.
  • While testing, lower the TTL to something like 300 seconds on any record you're actively changing - most hosts let you edit TTL per record. This means a mistake gets corrected everywhere within 5 minutes rather than a full day.
  • Once stable, you can raise TTL back up (or just leave it - a longer TTL on a record that never changes has essentially no downside, since content changes now happen behind our CNAME, not in your zone).
  • Global propagation is not instantaneous even after your authoritative TTL expires: recursive resolvers around the world (your ISP, corporate DNS, public resolvers like 8.8.8.8 or 1.1.1.1) each cache independently. Budget up to 24-48 hours for full global propagation on a first-time record, even though most resolvers pick it up within minutes to a couple of hours.
  • Changing an existing record's value is generally faster to propagate than adding a brand-new record type at a brand-new name, because the record type/name pair is often already "known" to be non-existent in negative caches - that negative cache also has its own TTL (governed by the zone's SOA minimum/negative-TTL field) and can itself take a while to expire.
ScenarioTypical wait before it's usable everywhere
New CNAME record, default TTL (1 hr)A few minutes to ~2 hours
New CNAME record, TTL lowered to 300s beforehandMinutes to ~30 minutes
Changing an existing CNAME's targetGoverned by the old record's TTL - wait that long
First-ever query for a name that returned NXDOMAIN beforeCan lag due to negative caching (up to the zone's negative TTL)
Tip If you know you'll be setting up several of these records in the same session, lower TTLs on the relevant hosts a day ahead where your host allows scheduling, or simply expect to wait out one full default-TTL cycle before verifying - don't panic and re-create records if a lookup fails in the first few minutes.

---

Verify it worked

Once you've published a record, confirm it before moving on - don't assume a save in your DNS host's UI means the internet has caught up.

  1. Use the in-app verifier first. Every service builder (/dmarc, /spf, /dkim, /mta-sts, /bimi) has a Verify button that checks live DNS and reports exactly what it sees, plus what's still wrong if verification fails.
  2. Cross-check with the DNS lookup tool at app.dmarcengine.com/lookup - query the exact record name (e.g. _dmarc.example.com, default._bimi.example.com) and confirm it resolves to the CNAME target you expect.
  3. Use the free public tools at dmarcengine.com/tools if you want a check that doesn't require sign-in, or want to double-check from a service outside DMARC Engine entirely.
  4. From the command line, dig is the fastest sanity check (works on macOS/Linux; on Windows, use nslookup or WSL):
   dig CNAME _dmarc.example.com +short
   dig CNAME s1._domainkey.example.com +short
   dig CNAME mta-sts.example.com +short
   dig CNAME _mta-sts.example.com +short
   dig CNAME default._bimi.example.com +short
   dig TXT example.com +short
   

A correctly delegated record returns the CNAME target (e.g. <slug>._dmarc.dmarcengine.com.) - if it returns nothing, or an NXDOMAIN, propagation isn't complete yet or the record wasn't saved correctly.

  1. Confirm the served content, not just the CNAME. Following a CNAME to its target and getting a response confirms delegation but not correctness. Use the verifier in-app (step 1) - it resolves through the CNAME and validates the actual policy/key/logo content on the other side, which a plain dig won't do for you.
  2. For MTA-STS specifically, also check the policy is reachable over HTTPS:
   curl -s https://mta-sts.example.com/.well-known/mta-sts.txt
   

You should get back a plain-text policy body starting with version: STSv1.
7. Check dashboard-wide coverage on app.dmarcengine.com/domains - the domain list shows a live status chip per service, so you can see at a glance which of the five are fully delegated and verified without opening each builder individually.
8. Give it 24-48 hours, then send a real test email to an external mailbox (Gmail is a good, strict test) and check the message headers for dkim=pass, spf=pass, dmarc=pass.

---

Common problems and fixes

Verification fails immediately after saving the record.
Almost always propagation delay, not a mistake. Wait out the old TTL (or the default TTL if this is a new record - commonly 5 minutes to 1 hour) and retry. If it still fails after several hours, re-check the exact host name - a stray extra .example.com typed into a field that already appends the domain is the most common cause (e.g. entering _dmarc.example.com in a field that only wants _dmarc, producing _dmarc.example.com.example.com).

Cloudflare record verifies for DNS but mail authentication still fails.
Check the proxy status. If the little cloud icon next to the record is orange, switch it to grey ("DNS only"). Proxied records resolve to Cloudflare's edge IPs for HTTP traffic, not the actual CNAME target mail systems need to follow.

"Multiple SPF records found" error.
You have more than one TXT record starting with v=spf1 at the domain apex. Consolidate to a single TXT record containing our include: - delete the others. This is a hard RFC 7208 rule: two SPF records is a permanent fail, not a "last one wins" situation.

SPF still exceeds 10 lookups after adding the DMARC Engine include.
This means another SPF include or mechanism was added outside the flattening chain - for example, someone appended include:_spf.google.com directly next to include:<slug>.spf.dmarcengine.com in the same TXT record. Remove any manually added include:/a:/mx:/ptr: mechanisms; add every sender inside the SPF builder instead so it's accounted for in the flattening.

DKIM CNAME verifies but mail still isn't signed.
DNS-side delegation only publishes the public key. The sending platform must actually be configured to sign outgoing mail with the matching private key and selector - check your ESP/mail platform's own DKIM signing settings (unless you're using DMARC Engine's own outbound relay, in which case check the sending config in the app).

MTA-STS verifies in DNS but the HTTPS check fails.
Give the SSL-for-SaaS certificate a little longer to provision after adding mta-sts.example.com - this is usually near-instant but can occasionally take up to a few minutes on a brand-new hostname. If it's been over an hour, re-check the CNAME target is exactly mta-sts.dmarcengine.com with no typo, then re-verify from the MTA-STS builder.

BIMI logo doesn't appear in Gmail even though verification passes.
Two likely causes: (1) your DMARC policy isn't yet enforcing at p=quarantine/pct=100 or p=reject - Gmail requires strong enforcement; or (2) you don't have a VMC - Gmail currently requires a Verified Mark Certificate for logo display even when everything else is correct, while some other providers (Yahoo, Apple Mail) display the SVG without one. Also allow a day or two after verification for provider-side caches to pick up eligibility.

Old record from a previous provider is still showing up.
DNS hosts don't automatically remove a record just because you added a new CNAME with a different name - if you migrated from a prior DMARC/SPF vendor, go back and delete their leftover records (a stale DKIM CNAME at an unused selector, an old _dmarc TXT, an old SPF include) so they don't conflict or confuse future audits.

Records look correct everywhere but the in-app verifier still shows "not delegated".
Double-check for a trailing-dot or copy-paste whitespace issue in the target - some DNS UIs silently truncate or duplicate a trailing dot. Re-copy the target fresh from the relevant builder page rather than retyping it.

---

The self-managed alternative

Delegation via CNAME is the default and recommended path because it removes ongoing DNS maintenance from your plate entirely. If your organisation has a policy requiring all published DNS values to be visible directly in your own zone (some security teams prefer this for auditability, or some DNS hosts genuinely don't support CNAMEs at certain names), every service also supports publishing the record's value directly instead of the CNAME:

  • DMARC: publish the v=DMARC1; p=...; rua=mailto:... text directly as a TXT record at _dmarc.example.com, copied from the DMARC builder's "manual value" view.
  • SPF: this is already the default shape - you're publishing a TXT record either way; self-managed simply means listing your own senders' includes directly instead of our single flattened include (you then own re-flattening whenever a sender's ranges change).
  • DKIM: publish the v=DKIM1; k=rsa; p=... public key directly as a TXT record at <selector>._domainkey.example.com, copied from the DKIM builder.
  • MTA-STS: you'd need to run and maintain your own HTTPS server and certificate for mta-sts.example.com serving the policy file, plus publish the _mta-sts id TXT and _smtp._tls TLS-RPT TXT directly.
  • BIMI: host your own compliant SVG (and VMC, if applicable) somewhere with HTTPS, and publish the v=BIMI1; l=...; a=... value directly as a TXT record at <selector>._bimi.example.com.

Every builder page has a toggle or "view manual record" option showing the raw value alongside the CNAME, so switching between hosted and self-managed for any single service is a one-click decision - you're never locked in.

Note The trade-off is real: self-managing means you're responsible for keeping SPF under the lookup limit as senders change, rotating DKIM keys, renewing the MTA-STS certificate before it expires, and updating BIMI if your logo or VMC changes. Most customers delegate everything and only self-manage a record where a specific policy requires it.

---

Frequently asked questions

Can I delegate some services and self-manage others?
Yes. Delegation is decided per service, not all-or-nothing. It's common, for example, to delegate DMARC, DKIM, MTA-STS and BIMI but keep SPF self-managed if a security team wants every sender include visible directly in the zone.

Does delegating DNS mean DMARC Engine can see or change my other DNS records?
No. A CNAME only tells resolvers to follow that specific name to our servers for that specific record. We have no access to your DNS zone, your registrar account, or any other record you publish. You add and remove our CNAMEs the same way you'd manage any other DNS record.

What happens if I delete the CNAME later?
The record simply stops resolving - mail authentication for that service reverts to whatever it was before (typically nothing, if this was your first setup). There's no ongoing dependency beyond DNS resolution; deleting the CNAME cleanly disables that service's hosted delegation with no side effects elsewhere.

Do I need to renew or maintain anything once the CNAME is in place?
No - that's the entire point of delegation. SPF re-flattening, DKIM rotation, MTA-STS certificate renewal, and BIMI logo/VMC updates all happen behind the CNAME. You only touch DNS again if you want to change the record's name (e.g. add a new DKIM selector) or remove a service.

Why can't SPF be a CNAME like the others?
SPF's TXT record must live at your domain's apex (the bare root), which already needs A/MX records - a name can't have both a CNAME and other record types simultaneously. Instead, the hosted approach uses an include: mechanism inside a normal TXT record you publish once; we maintain the flattened chain it points to.

I use Cloudflare - do the CNAMEs need to be proxied (orange cloud)?
No - set every DMARC Engine CNAME to DNS only (grey cloud). Proxying breaks resolution for mail-authentication and policy lookups, which need to reach our infrastructure directly rather than Cloudflare's HTTP proxy layer.

How long until my domain shows as fully covered?
Once every record verifies in the app, coverage is immediate on our side. Real-world mail flow (an actual message showing dkim=pass; spf=pass; dmarc=pass in headers) can lag a little behind full DNS propagation - allow up to 24-48 hours before treating a still-failing live test as a genuine problem rather than propagation lag.

Can I move a domain between DNS hosts without breaking delegation?
Yes, as long as you re-create the same CNAME/TXT records at the new host before (or immediately after) the nameserver cutover. The targets don't change when you switch registrars or DNS providers - only where the records themselves live.

Where do I check overall coverage across all my domains?
app.dmarcengine.com/domains lists every domain with a per-service status chip. For deeper report analysis once DMARC is flowing, use /analytics, /reports, and set up /alerts for drift or failure notifications. If you suspect a spoofing or abuse issue, check /threats.

Is there a single place to see exactly what's wrong with a record right now?
Yes - each service's own page in the app (linked throughout this guide) shows a live "what's wrong" diagnosis alongside the expected record, and /lookup lets you query any name directly. For a broader compliance check, DMARC Engine also runs a full /audit across all five services at once.

Who do I contact if a record still won't verify after following this guide?
Reach out via app.dmarcengine.com/support with your domain name and the specific record you're stuck on - support can see the exact hosted target and current DNS state for your domain and diagnose faster than a generic troubleshooting pass.

---

For a no-signup sanity check on any domain, try the free DMARC, SPF and DKIM checker tools.

Share

See where your domain stands today

Run a free DMARC scan, then let us take you to enforced p=reject with no email outage.