DNS Records for Email: SPF, DKIM, DMARC, and How Mail Authentication Works
How DNS really works for email: nameservers, SPF, DKIM, and DMARC explained, the attacks they stop, and the exact records for Google Workspace, SES, Mailgun, and Cloudflare.
Every time you send an email, visit a website, or verify a domain, a quiet system in the background decides where your request goes and whether it is trusted: DNS, the Domain Name System. For mail in particular, a handful of DNS records are the difference between your messages landing in the inbox and landing in spam, and between an attacker being able to impersonate your domain and being firmly locked out. This guide explains what DNS records are, how nameservers and delegation actually work, every record type that matters for email and security, the SPF/DKIM/DMARC trio that stops spoofing, the attacks DNS is involved in, and the exact records you add for Google Workspace, Amazon SES, Mailgun, and Cloudflare, with real examples and how to verify each one.
What DNS Is, in One Picture
Computers find each other by IP address (like 192.0.2.10), but humans use names (like example.com). DNS is the global phone book that translates names into the information needed to reach them. When something looks up a name, the request travels down a hierarchy:
- A recursive resolver (usually run by your ISP or a service like
1.1.1.1) receives the question "what isexample.com?" and does the legwork. - It asks a root server, which points it to the servers for the
.comTLD (top-level domain). - The
.comservers point it to the authoritative nameservers forexample.com: the servers that hold the real, definitive records for that domain. - Those authoritative nameservers return the answer, which the resolver caches and hands back.
Analogy. Finding a phone number used to mean: call directory assistance (the resolver), who checks the master index for which regional book covers the name (root and TLD), then opens that specific book (the authoritative nameserver) and reads you the number (the record). DNS is that whole chain, automated and finishing in milliseconds.
Here is the same chain as a picture, following one lookup of example.com:
Your device
│ "what is example.com?"
▼
┌─────────────────┐ ┌──────────────┐
│ Recursive │ ──> │ Root servers │ "ask the .com servers"
│ resolver │ <── └──────────────┘
│ (1.1.1.1, ISP) │ ┌──────────────┐
│ │ ──> │ .com TLD │ "ask example.com's nameservers"
│ │ <── └──────────────┘
│ │ ┌────────────────────────┐
│ │ ──> │ Authoritative │ "here is the record"
│ │ <── │ nameservers (the truth)│
└─────────────────┘ └────────────────────────┘
│ caches the answer for its TTL, returns it
▼
Your device connectsThe key idea for everything below: the authoritative nameservers are the single source of truth for a domain's records. Whoever controls them controls where your website and email go. That is why securing them matters, and why "pointing your domain somewhere" almost always means changing nameservers.
Two Kinds of DNS Server: Askers and Answerers
The word "DNS server" gets used for several very different things, and untangling them clears up most confusion. There are really only two roles.
Recursive resolvers are the askers. They do not know any answers themselves; their job is to go find the answer by asking around the chain above, then cache it and hand it back to you. Your ISP runs one of these, and it is the default your router uses. The public resolvers 1.1.1.1 (Cloudflare) and 8.8.8.8 (Google) are the exact same role, just run by someone else. When you "change your DNS" in your router or operating system settings, all you are doing is choosing a different asker, for speed, privacy, or to bypass ISP-level blocking. It affects only your lookups.
Authoritative nameservers are the answerers. They hold real, definitive records and simply respond when asked. Root servers, TLD servers, and a domain's own nameservers are all authoritative, each for their own slice. When you "change your nameservers" at your registrar, you are choosing a different answerer for your domain, which affects how everyone in the world looks it up.
Analogy. A recursive resolver is a research assistant you send to the library. An authoritative nameserver is a specific book on a specific shelf. The assistant does not memorize the library; they walk the aisles, find the right book, read you the answer, and remember it for next time. The books never leave the shelf; they just contain truth.
The big Cloudflare confusion, resolved.1.1.1.1(Cloudflare's public resolver) and "Cloudflare as your domain's DNS host" (Cloudflare's authoritative nameservers) are two completely different products that share a brand. One is the asker you point your laptop at; the other is the answerer that holds your domain's records. Same with Google:8.8.8.8is a resolver, while Google Cloud DNS is an authoritative host. So "changing your DNS" (picking a resolver, affects only you) and "changing your nameservers" (picking an authoritative host, affects the whole world's view of your domain) are opposite ends of the chain.
What the Root Server Actually Is
The root sits at the very top of the DNS tree, above .com, .in, .org, everything. Every domain name technically ends in an invisible dot you never type: www.google.in is really www.google.in., and that final dot is the root. So the root is the starting point of the entire naming system.
The thing people get wrong: the root server does not know google.in, or even google. It knows exactly one category of fact: for each TLD, which servers are in charge of it. Its entire knowledge is a small file (the root zone, only a couple of megabytes) listing roughly 1,500 TLDs and pointing each at its operator's nameservers. It is a signpost, not a destination.
.in → ask India's TLD nameservers
.com → ask Verisign's .com nameservers
.org → ask .org's nameservers
... about 1,500 entries, one per TLD, no individual domains ...Who maintains it is three separate jobs, which is why "who runs the root" has no single answer. ICANN (through its IANA function) decides the content, editing the master list when a TLD is created or changes its nameservers. A maintainer publishes that file. And 12 independent organizations operate the 13 root server identities named A through M, a mix of US universities, government agencies, and nonprofits worldwide, so no single company owns the root.
The "13 servers" myth. There are 13 identities (A to M), not 13 machines. Each letter is actually hundreds of physical servers spread across the planet using anycast: many machines share one IP address, and the network routes you to the nearest one. There are well over 1,500 physical root instances globally, which is why the root is always fast and never down. Think of the 13 letters as 13 brands of information desk, each with thousands of identical franchise locations; you are always sent to the nearest one.
How it handles a .in lookup shows the root doing its one job and stepping aside. Looking up www.google.in, your resolver first asks a root server, which answers: "I do not know google.in, but for anything ending in .in, go ask India's TLD nameservers." The resolver then asks the .in servers, which say "google.in is delegated to Google's nameservers," and finally Google's nameservers return the actual address. The root's contribution is only the first hop, pointing at the right TLD; it never sees google or www.
Each TLD has its own operator, a registry, separate from the root: .in is run by NIXI (India's National Internet Exchange) through its IRRINN registry, .com by Verisign, .uk by Nominet, and so on. The root points at each registry; the registry knows which nameservers each registered domain uses; the domain's own nameservers hold the actual records. Three tiers, three different operators, each knowing only its own slice.
What "Authoritative" Means: Zones, SOA, and Delegation
A nameserver is authoritative for a domain when it holds the real, original records: the master copy. When a resolver finally reaches an authoritative nameserver, it gets the definitive answer, not a cached guess and not a referral. That is the entire meaning of the word: "I am the source of truth for this zone, ask me and you get the actual record." It is simply the label for the answerer role, the opposite of a resolver that asks around and caches copies.
Analogy. An authoritative nameserver is the original signed document in the filing cabinet. A resolver is someone who photocopied it last week and is reading you the copy. When you need to be certain, you go to the original in the cabinet; everyone else is working from copies (caches) that expire.
Three words that get used interchangeably actually mean different things, and separating them removes most confusion:
- A nameserver is a machine or service that answers DNS queries, the specific thing like
aria.ns.cloudflare.com. A domain normally has two or more for redundancy. - A DNS host (or DNS provider) is the company that runs your authoritative nameservers and gives you a control panel to edit records: Cloudflare, Route 53, your registrar's built-in DNS. This is where you log in to add an A or MX record.
- Authoritative is the property of holding the master records.
In one sentence: your DNS host runs the authoritative nameservers for your domain, and you edit your records in the host's panel.
The zone, and the records that define it
The full collection of records for one domain is called a zone, and the authoritative nameserver holds the zone file. Two records in every zone are special because they define it as authoritative:
- The NS records list which nameservers are authoritative for the zone. The zone even names its own authoritative servers, and this set is what must match the delegation configured at your registrar.
- The SOA record (Start of Authority) is the zone's title page: it names the primary nameserver, an admin contact, a serial number that increments on every edit, and timing values. Every authoritative zone has exactly one SOA, and its presence is literally what marks the start of an authoritative zone.
This is the underlying reason you cannot put a CNAME on the bare domain (the apex): the apex must already hold the NS and SOA records, and a CNAME is not allowed to share a name with other records.
Primary and secondary nameservers
Authoritative service usually runs on more than one server so a single failure does not take the domain offline. The primary (master) is where the zone is actually edited and holds the original. Secondary (slave) servers copy the zone from the primary through a zone transfer and answer queries identically; they are authoritative too, just read-only replicas kept in sync. Managed hosts like Cloudflare and Route 53 hide this entirely and replicate across their own fleet, so you simply edit records; you mostly meet primary and secondary directly when running your own DNS or combining two providers for resilience.
Analogy. The primary is the head office where policy is written; secondaries are branch offices that receive the updated binder and answer identically. Callers cannot tell which office they reached, and that is the point.
Authority is delegated, not self-declared
Tying it back to the root chain: the resolver works downward and every hop is authoritative for its level, handing off to the next. The root is authoritative for the dot and points at the TLD; the .com TLD is authoritative for com and points at your domain's nameservers; your DNS host's nameservers are authoritative for example.com and give the final record. Authority is delegated down the tree one tier at a time.
That is the crux: a nameserver is not authoritative because it says so, but because the tier above it delegated that authority. The NS records you set at your registrar are that delegation, telling the TLD "these nameservers are the source of truth for my domain." Break the delegation and the world stops treating your nameservers as authoritative, even though the records still sit right there untouched.
Nameservers, Registrars, and DNS Hosts (the trio people confuse)
Three distinct roles get muddled constantly, and untangling them clears up most DNS confusion:
- The registrar is who you bought the domain from (Namecheap, GoDaddy, Cloudflare Registrar). They handle the registration and billing, and critically, they hold the setting for which nameservers your domain uses.
- The DNS host is who runs the authoritative nameservers that actually answer queries and store your records (Cloudflare, Route 53, the registrar's own DNS). This is where you add A, MX, TXT records.
- The nameservers are the specific servers the DNS host assigns you, like
aria.ns.cloudflare.comandrob.ns.cloudflare.com.
These can all be the same company or three different ones. The connection between them is delegation: at your registrar, you set your domain's nameservers to point at your DNS host. That tells the .com registry "for this domain, go ask these servers." Until that delegation points at the right nameservers, nothing you add in the DNS host takes effect.
Analogy. The registrar is the government office where your address is officially on record. The DNS host is the receptionist who actually answers when someone asks "where is this company?" Changing nameservers at the registrar is updating the official record to say "from now on, this new receptionist speaks for us." Until that update, callers reach the old receptionist no matter what the new one knows.
This is exactly what "moving a domain to Cloudflare" means in practice. Cloudflare assigns you two authoritative nameservers, and you go to your registrar and replace the existing nameservers with Cloudflare's. From that point, Cloudflare answers all DNS queries for your domain.
Gotcha: DNSSEC and nameserver changes. If your domain has DNSSEC enabled (a security feature covered later), you must turn it off at the registrar before changing nameservers. Switching nameservers while DNSSEC is active can make the domain unreachable, because the cryptographic signatures will no longer match the new provider. You re-enable it after the move.
TTL and Propagation: Why Changes Are Not Instant
Every DNS record carries a TTL (time to live), a number of seconds telling resolvers how long they may cache the answer before asking again. A record with a TTL of 3600 can be cached for an hour, so a change you make might take up to an hour to be seen by someone whose resolver cached the old value.
"Propagation" is the informal word for waiting out those caches worldwide. It is not that your change crawls across the internet; it is that caches everywhere expire at different times. The practical implications:
- Lower the TTL before a planned change so the old value expires quickly, then raise it again after.
- A change can appear instantly for you and still be stale for someone else whose cache has not expired.
- Most records resolve within minutes to a couple of hours; the "up to 48 to 72 hours" figure is a worst case, and if mail is not flowing after an hour it is almost always a configuration error, not propagation.
Analogy. TTL is the "best before" date on a cached answer. Resolvers keep using the cached value until that date passes, then fetch a fresh one. Shortening the date ahead of a change means everyone refreshes sooner.
The Record Types That Matter
DNS records all share a shape: a name (the hostname), a type, a value, and a TTL. Here are the types you actually deal with, each with its job.
A and AAAA map a name to an IP address. A points to an IPv4 address, AAAA to an IPv6 address. This is how example.com resolves to a web server.
example.com. A 192.0.2.10
example.com. AAAA 2001:db8::10CNAME is an alias: it points one name at another name rather than an IP. Looking up the alias follows the chain to wherever it points. Email providers love CNAMEs because they let the provider control the underlying value (and rotate keys) while you just point at them.
www.example.com. CNAME example.com.Gotcha: no CNAME at the root. You cannot put a CNAME on the bare domain (example.com itself, the "zone apex"), because the apex must hold other mandatory records (like the zone's SOA and NS records) and a CNAME is not allowed to coexist with them. Providers like Cloudflare work around this with "CNAME flattening," which resolves the alias and returns the final IP, but plain DNS forbids it.NS records list the authoritative nameservers for a zone. These are what delegation points at.
MX (Mail eXchanger) is the record that routes email. It tells sending servers which host to deliver your domain's mail to, with a priority number (lower number is tried first). Without an MX record, your domain cannot receive mail.
example.com. MX 1 smtp.google.com. (priority 1, tried first)
example.com. MX 10 mail.example.com. (priority 10, a backup)TXT records hold arbitrary text, and they are the workhorse of email security: SPF, DKIM, and DMARC all live in TXT records. A long TXT value over 255 characters gets split into multiple quoted strings, which the receiving application stitches back together, so a 2048-bit DKIM key that exceeds the limit is normal and handled automatically by good providers.
CAA (Certification Authority Authorization) controls which certificate authorities are allowed to issue TLS certificates for your domain, narrowing who can mint a valid HTTPS cert in your name.
example.com. CAA 0 issue "letsencrypt.org"PTR is reverse DNS: it maps an IP address back to a name, the opposite of an A record. It matters for mail because many receiving servers reject or distrust mail from an IP whose PTR does not match the sending hostname. PTR records live with whoever controls the IP address (your mail server's host), not in your normal domain zone.
SRV locates a service (host and port) for protocols like SIP or XMPP. You will see it occasionally for things like auto-configuration, but it is rarely central to mail.
The Email Trinity: SPF, DKIM, DMARC
This is the heart of mail security, and the three work as a team. The problem they solve: by default, anyone can send an email claiming to be from your domain, because the "From" address is just text the sender types. SPF, DKIM, and DMARC let receiving servers verify that a message genuinely came from someone you authorized, and decide what to do if it did not.
Analogy. Think of an email arriving at a secure building. SPF is the guest list: is the courier who delivered this from a company we authorized to deliver for us? DKIM is a tamper-proof wax seal: is this envelope sealed with our genuine seal, unbroken? DMARC is the security policy posted at the door: if a delivery fails the guest-list check and the seal check, do we let it in, hold it for inspection, or turn it away, and please send us a report of what was rejected.
SPF: who is allowed to send
SPF (Sender Policy Framework) is a TXT record listing which mail servers are authorized to send email for your domain. A receiving server checks the sending server's IP against this list.
example.com. TXT "v=spf1 include:_spf.google.com ~all"Reading it: v=spf1 declares the version. include:_spf.google.com says "also trust everything in Google's SPF record" (this is how you authorize Google Workspace to send for you). ~all is the catch-all at the end that handles everything not matched.
The ending qualifier is the important nuance:
~allis softfail: mail from unlisted servers is allowed but marked suspicious. The common, safe default while you are setting up.-allis hardfail: mail from unlisted servers should be rejected outright. The stricter, more secure end state.
Gotcha: one SPF record, and the 10-lookup limit. A domain may have only one SPF record. If you use several senders (Google for staff mail, Mailgun for app mail), you do not add a second SPF record; you merge theirinclude:values into the one record. SPF also has a hard limit of 10 DNS lookups when it evaluates; exceed it (too manyinclude:mechanisms) and SPF fails with apermerror, silently hurting deliverability. Keep the chain lean.
# Merging Google + Mailgun into ONE record (correct):
example.com. TXT "v=spf1 include:_spf.google.com include:mailgun.org ~all"DKIM: a cryptographic signature
DKIM (DomainKeys Identified Mail) attaches a digital signature to every outgoing message, created with a private key held by your mail provider. The matching public key is published in your DNS as a TXT (or CNAME pointing to the provider's TXT). The receiving server fetches the public key and verifies the signature, proving the message really came from your domain and was not altered in transit.
The public key lives at a special name: the selector plus ._domainkey plus your domain. The selector (a label like google or mx) lets you run multiple keys at once, which is what makes key rotation possible without downtime.
google._domainkey.example.com. TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkq... (long public key)"Analogy. DKIM is a wax seal stamped with a signet ring. Your provider holds the unique ring (the private key) and stamps every letter. You post a picture of the ring's pattern publicly (the public key in DNS) so anyone receiving a letter can confirm the seal matches and the envelope was never opened. The selector is like having several rings in rotation, each labeled, so you can switch to a new one while the old one is still trusted.
Gotcha: the selector and the underscore. The record name must be exactlyselector._domainkey.yourdomain.com. Two common errors are providers double-appending the domain (creatinggoogle._domainkey.example.com.example.com) and DNS panels that strip the required underscore. Always verify the final name with a lookup.
DMARC: the policy that ties it together
DMARC (Domain-based Message Authentication, Reporting and Conformance) is the TXT record that tells receivers what to do when SPF and DKIM checks fail, and asks them to send you reports. It lives at the fixed name _dmarc.yourdomain.com.
_dmarc.example.com. TXT "v=DMARC1; p=none; rua=mailto:dmarc@example.com; adkim=r; aspf=r"The policy (p=) is the part with teeth, and you ratchet it up over time:
p=noneis monitor only: take no action, just send reports. Where everyone starts, to see who is sending as you without breaking anything.p=quarantinesends failing mail to spam.p=rejectblocks failing mail outright. The strong end state that actually stops spoofing.
The rua= address receives daily aggregate reports showing every source sending as your domain and whether they passed. Alignment (adkim/aspf, relaxed r or strict s) requires that the domain that passed SPF or DKIM matches the visible "From" domain, which is what stops an attacker from passing SPF with their own domain while displaying yours.
The crucial DMARC insight. SPF and DKIM alone do not stop spoofing, because a forged email can fail both and still be delivered; receivers had no instruction to reject it. DMARC is what turns "this failed authentication" into "therefore reject it," and alignment is what ensures the authentication was for your domain, not just any domain. This is why a domain with SPF and DKIM but no DMARC (or p=none forever) is still spoofable.Here is the decision a receiving server actually makes, as a flow:
Incoming email claiming to be from you
│
▼
Does SPF pass AND align? ──yes──┐
│ no │
▼ │
Does DKIM pass AND align? ──yes──>├──> DMARC PASS ──> deliver normally
│ no │
▼ │
Both failed ──> read your DMARC policy (p=)
│
┌─────────┼─────────────┐
▼ ▼ ▼
p=none p=quarantine p=reject
deliver send to spam refuse outright
(+ report) (+ report) (+ report)"Align" is the part that defeats lookalike tricks: passing SPF or DKIM only counts if the domain that passed matches the visible From: domain. An attacker can pass SPF for their own domain, but it will not align with yours, so DMARC still fails.
Best practice path. Start atp=nonewith reporting, watch the aggregate reports until every legitimate sender (Google, Mailgun, your app) is passing and aligned, then move top=quarantine, and finallyp=reject. Jumping straight torejectbefore your senders are aligned will send your own legitimate mail to the void.
Reading a DMARC report
The rua reports are the feedback loop that makes tightening a policy safe. They arrive as XML (most people use a tool to render them), but stripped down, one aggregate report tells you, per sending source: the IP, how many messages it sent, and whether SPF and DKIM passed and aligned. Simplified, it reads like this:
Source IP Count SPF DKIM Aligned? Likely who
209.85.x.x 1,240 pass pass yes Google Workspace (legit)
198.61.x.x 320 pass pass yes Mailgun (legit)
185.220.x.x 47 fail fail no unknown sender (spoofing!)You read it top to bottom asking one question of each row: "is this a sender I recognize and authorized?" The first two rows are your real senders passing cleanly, so they are safe. The third is mail failing authentication and not aligned, which is either a forgotten legitimate sender you still need to authorize, or an actual spoofing attempt. You stay at p=none until every legitimate source is passing and aligned, then tightening to quarantine and reject only hurts the spoofers, not your real mail. This report is the single most useful artifact for moving a policy forward with confidence.
The modern add-ons
Briefly, three newer records build on the trinity. MTA-STS (with a TXT record plus a policy file) forces inbound mail to your domain to use encrypted TLS connections. TLS-RPT asks for reports about TLS failures. BIMI lets your verified brand logo appear next to your messages in supporting inboxes (Gmail, Yahoo, Apple Mail), which is both a trust signal and an anti-impersonation measure, because the logo only shows on authenticated mail.
BIMI is worth understanding a little deeper, because it is the business reason many organizations finally enforce DMARC. It is a TXT record at default._bimi.yourdomain.com pointing to your logo (an SVG in the strict "SVG Tiny PS" profile) and, usually, to a certificate:
default._bimi.example.com. TXT "v=BIMI1; l=https://example.com/logo.svg; a=https://example.com/vmc.pem"The hard gate, and the single most common reason BIMI fails to display, is that your DMARC policy must be at p=quarantine or p=reject with pct=100. A domain at p=none will not show a logo no matter how perfect the record, because mailbox providers treat logo display as a privilege of authenticated, enforcing senders. The certificate in the a= tag comes in two flavors: a VMC (Verified Mark Certificate) requires a registered trademark and is what unlocks Gmail's blue verified checkmark, while a CMC (Common Mark Certificate, introduced 2024 to 2025) accepts a logo with 12+ months of documented public use but no trademark, and shows the logo without the checkmark. The practical sequence everyone follows: get to DMARC enforcement first, then obtain the certificate, because the enforcement is the gate and the harder of the two. They are worth knowing by name; the trinity is what you must get right first.
How These Records Stop Attacks
The records above are not box-ticking; they directly defeat specific attacks. This is the "attacks" angle, made concrete.
Email spoofing and phishing. An attacker sends a message with From: ceo@yourcompany.com to trick an employee into wiring money. With the trinity in place: the message comes from the attacker's server, which is not in your SPF list, so SPF fails. The attacker cannot forge your DKIM signature because they do not have your private key, so DKIM fails. Your DMARC policy at p=reject then tells the receiving server to refuse the message, and alignment ensures the attacker cannot sneak through by authenticating their own lookalike domain. The forgery is rejected before it reaches the inbox.
Subdomain takeover. If you create a CNAME pointing a subdomain (say promo.example.com) at a third-party service, then later stop using that service without removing the record, the record is now "dangling": it points at something you no longer control. An attacker who claims that abandoned third-party resource can serve content from your subdomain, capturing trust, cookies, and credibility. The fix is hygiene: remove DNS records the moment the service behind them is decommissioned.
DNS hijacking and cache poisoning. If an attacker compromises your registrar account or DNS host, they can repoint your records, sending your visitors and mail to their servers. Cache poisoning tricks a resolver into caching a forged answer. The defenses are guarding the registrar and DNS-host accounts fiercely (strong unique passwords, multi-factor, registrar lock) and DNSSEC, which cryptographically signs your DNS records so resolvers can detect tampering. DNSSEC does not encrypt DNS; it proves the answer you got is the genuine one the domain owner published.
Looking like a spammer (deliverability as defense). Even legitimate senders get treated as hostile if their setup is sloppy. A missing or mismatched PTR record, a failing SPF, or no DKIM makes receiving servers distrust you, and your real mail lands in spam. Good authentication is both a shield against impersonation and a passport that gets your genuine mail delivered.
Gotcha: an SPF record is not optional armor you can skip. Without SPF, anyone can send spoofed mail as your domain and receivers have no way to tell. Without DKIM, a man-in-the-middle can alter your messages undetected. Without DMARC, neither check has any enforcement. The three together are the minimum baseline, and as of 2024 the major mailbox providers (Google, Yahoo, then Microsoft) began requiring them for bulk senders, so they are now effectively mandatory, not nice-to-have.
Subdomain vs Root: Where to Send From
A decision that quietly determines your fate is which domain your different mail streams send from. The strong best practice is to send bulk and application mail from a dedicated subdomain (like mail.example.com or news.example.com), keeping your root domain (example.com) for your important person-to-person email through Google Workspace or similar.
The reason is reputation isolation. Mailbox providers track sender reputation per domain. If you blast a marketing campaign or a buggy app sends a flood of bounces, that damage lands on whichever domain sent it. If that domain is your root, your CEO's one-to-one emails start going to spam too, because they share the reputation. Sending the risky, high-volume streams from a subdomain quarantines any reputation damage to that subdomain, leaving your primary mail unaffected.
Analogy. It is the difference between doing your messy chemistry experiments in a separate garage versus on the kitchen counter. If something explodes in the garage (the sending subdomain), your kitchen (your primary mail) is untouched. Mix them, and one bad batch ruins dinner for everyone.
This is exactly why Mailgun, SES, and similar services recommend a subdomain. It also keeps DNS clean: the subdomain gets its own SPF, DKIM, and MX records that cannot collide with your root domain's existing mail setup. Your DMARC policy on the root can still cover subdomains (via the sp= subdomain-policy tag), so you keep one enforcement umbrella while isolating reputation.
Email Forwarding Breaks SPF (and Why DKIM Saves You)
A genuinely common and confusing failure: a message you sent passes authentication fine, but when it is forwarded, it suddenly fails and lands in spam. This trips up almost everyone at some point, and the reason is structural.
When mail is forwarded (say alias@example.com auto-forwards to a personal Gmail), the forwarding server becomes the one delivering the message to the final destination. But that forwarding server is not in the original sender's SPF list, so SPF fails at the final hop, because the IP delivering the mail does not match the authorized senders of the original domain.
DKIM survives forwarding, though, because the DKIM signature is part of the message itself and travels with it unchanged (as long as the forwarder does not modify the body). So a forwarded message typically fails SPF but still passes DKIM, and because DMARC needs only one of the two to pass and align, DKIM is what keeps forwarded mail authenticated. This is a concrete reason DKIM is not optional: it is the only one of the two that reliably survives the real-world journey of an email.
The patch for the gap: ARC. When a forwarder does modify a message (adding a footer, a mailing-list tag, or a subject prefix), it can break DKIM too, and then forwarded mail fails everything. ARC (Authenticated Received Chain) was created for this: the forwarding server records "I received this and it authenticated correctly when it reached me," cryptographically sealing that attestation so the final receiver can choose to trust the forwarder's word. ARC does not replace SPF, DKIM, or DMARC; it is a trust-preserving relay for legitimate forwarders and mailing lists. You do not usually configure ARC yourself; major providers like Google handle it, but knowing it exists explains why some forwarded and mailing-list mail still gets delivered despite failing plain SPF and DKIM.
Provider Walkthrough: Google Workspace
Google Workspace is mail hosting, so you point your domain's mail at Google and authenticate it. The records:
MX (route mail to Google). Google simplified this in 2023 to a single record. New setups use one MX:
example.com. MX 1 smtp.google.com.The older five-record set (aspmx.l.google.com and four altN.aspmx.l.google.com backups) still works and is fully supported; if it is already running, leave it alone.
Domain verification (TXT). Before Google enables your mail, it has you prove you own the domain by publishing a TXT record it gives you (a string like google-site-verification=...) at the root.
SPF (authorize Google to send). One TXT record:
example.com. TXT "v=spf1 include:_spf.google.com ~all"DKIM (sign outgoing mail). In the Admin console under Apps, Google Workspace, Gmail, Authenticate email, you generate a key (choose 2048-bit). Google gives you a TXT record at the google selector. You publish it, wait for propagation, then click "Start authentication" in the console to turn on signing.
google._domainkey.example.com. TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0B... "DMARC. You add the _dmarc TXT record yourself (Google does not auto-create it), starting at p=none and tightening over time.
Gotcha: wait for DKIM to appear. After you first enable Gmail, Google needs up to 24 to 72 hours before the DKIM key is even available to generate in the console, and the console can keep showing "you must update DNS" for up to 48 hours after you have already published correctly. Verify the record yourself with a lookup rather than trusting the console status alone.
Provider Walkthrough: Amazon SES
Amazon SES (Simple Email Service) is a sending service for application and bulk mail, so the records authenticate SES to send as you. SES leans on CNAMEs so it can manage and rotate keys for you.
Domain identity and Easy DKIM (three CNAMEs). You create a domain identity in the SES console and enable Easy DKIM (the recommended mode, where SES holds the keys). SES generates three CNAME records that point at SES-managed DKIM keys. You publish all three:
abc123._domainkey.example.com. CNAME abc123.dkim.amazonses.com.
def456._domainkey.example.com. CNAME def456.dkim.amazonses.com.
ghi789._domainkey.example.com. CNAME ghi789.dkim.amazonses.com.Because these point at SES, when SES rotates the underlying keys the change is transparent and you never touch DNS again. (If you use Route 53 on the same account, SES can publish these for you automatically.)
Custom MAIL FROM (SPF alignment). By default SES sends with a MAIL FROM of amazonses.com, which breaks SPF alignment for your domain. To fix it you configure a custom MAIL FROM subdomain (like mail.example.com), and SES gives you an MX record and a TXT (SPF) record to publish for that subdomain:
mail.example.com. MX 10 feedback-smtp.us-east-1.amazonses.com.
mail.example.com. TXT "v=spf1 include:amazonses.com ~all"DMARC. As always, you publish the _dmarc TXT yourself.
Gotcha: thed=amazonses.comalignment trap. If you verify only an email address (not the domain) or skip Easy DKIM, SES signs withd=amazonses.comrather than your domain, so DMARC alignment fails even though DKIM "passes." Enable Easy DKIM on the domain identity so SES signs asd=example.com. Also note SES starts in a sandbox that only sends to verified addresses; you request production access to send to anyone.
Provider Walkthrough: Mailgun
Mailgun is another sending service (API and SMTP), and it strongly recommends sending from a subdomain like mail.example.com so its records never collide with your root domain's existing mail. It groups records as Sending (TXT), Receiving (MX), and Tracking (CNAME).
Sending: two TXT records (SPF + DKIM), required.
mail.example.com. TXT "v=spf1 include:mailgun.org ~all"
mx._domainkey.mail.example.com. TXT "k=rsa; p=MIGfMA0GCSq... (DKIM public key)"If your root domain already has an SPF record, you do not add a second one; you merge include:mailgun.org into it.
Receiving: two MX records, optional. Only add these if you want Mailgun to receive inbound mail for that subdomain. Crucially, do not point your MX at Mailgun if your mail is already handled elsewhere (like Google Workspace), or you break inbound delivery.
mail.example.com. MX 10 mxa.mailgun.org.
mail.example.com. MX 10 mxb.mailgun.org.Tracking: one CNAME, optional. This enables open and click tracking.
email.mail.example.com. CNAME mailgun.org.Then you click "Verify DNS Settings" in Mailgun and watch for green checkmarks.
Gotcha: only the two TXT records are mandatory. People over-add. The SPF and DKIM TXT records are all that is required to send. MX is only for receiving, and adding it blindly can hijack your existing inbound mail. The CNAME is only for tracking. Add what you need, not everything shown.
Provider Walkthrough: Cloudflare
Cloudflare is different from the three above: it is not a mail service. It is a DNS host (and often registrar and reverse proxy), so it is where you add the records the mail services give you. Two Cloudflare-specific concepts matter enormously for mail.
Nameservers. When you onboard a domain, Cloudflare assigns you two authoritative nameservers and you set them at your registrar (unless you also bought the domain through Cloudflare Registrar, in which case it is automatic). From then on Cloudflare answers all your DNS.
The orange cloud vs grey cloud (proxy status). This is the single biggest Cloudflare-and-email gotcha. Each A, AAAA, and CNAME record has a proxy toggle:
- Orange cloud (Proxied): web traffic for that record routes through Cloudflare's network, getting caching, DDoS protection, and a hidden origin IP. Correct for your website's A and CNAME records.
- Grey cloud (DNS only): Cloudflare just returns the record's real value and does not proxy. Correct for anything that is not web traffic.
The rule for mail: mail-related records must be grey-clouded (DNS only). MX and TXT records are always DNS-only anyway (Cloudflare cannot proxy them), but any CNAME used to verify a mail service (like SES's DKIM CNAMEs or Mailgun's tracking CNAME) must be grey cloud, or verification fails, because proxying replaces the value the mail provider needs to read with Cloudflare's own.
# Mail records on Cloudflare are always DNS only (grey cloud):
example.com. MX 1 smtp.google.com. (DNS only)
example.com. TXT "v=spf1 include:_spf.google.com ~all"
abc123._domainkey.example.com. CNAME abc123.dkim.amazonses.com. (grey cloud!)Gotcha: a proxied DKIM CNAME silently fails verification. If you leave the orange cloud on a DKIM-verification CNAME, Cloudflare answers with its own proxy value instead of the provider's key, and the mail service reports the record as not found. The fix is one click: toggle it to grey cloud (DNS only). This trips up nearly everyone integrating SES or Mailgun behind Cloudflare.
Note on PTR and Cloudflare. Because proxied domains answer with Cloudflare's shared IPs, you do not set reverse-DNS PTR records at Cloudflare for mail; PTR is configured wherever your sending mail server's IP actually lives. Cloudflare also offers an Email Security wizard that can generate the SPF/DKIM/DMARC records for you.
Quick Reference: Records at a Glance
| Record | Purpose | Lives at | Used for mail? |
|---|---|---|---|
| A / AAAA | name to IPv4 / IPv6 address | the hostname | no (web) |
| CNAME | alias one name to another name | the hostname (not the root) | DKIM/tracking verification |
| NS | lists the authoritative nameservers | the zone | indirectly (delegation) |
| MX | routes incoming mail, with priority | the domain receiving mail | yes, receiving |
| TXT | arbitrary text; carries SPF/DKIM/DMARC | varies (see below) | yes, the security trio |
| CAA | which CAs may issue TLS certs | the domain | no (TLS) |
| PTR | reverse DNS, IP back to a name | with the IP's owner | yes, anti-spam |
| SRV | locates a service (host + port) | service-specific | rarely |
And the email-security records specifically, by the name they live at:
| Record | Name (where it lives) | Type | Example value (abbreviated) |
|---|---|---|---|
| SPF | example.com (root) | TXT | v=spf1 include:_spf.google.com ~all |
| DKIM | selector._domainkey.example.com | TXT or CNAME | v=DKIM1; k=rsa; p=MIIB... |
| DMARC | _dmarc.example.com | TXT | v=DMARC1; p=reject; rua=mailto:... |
| BIMI | default._bimi.example.com | TXT | v=BIMI1; l=...svg; a=...pem |
Verifying Your Records
Never trust a provider's "verified" badge alone; check the DNS directly. The dig command (or nslookup on Windows) queries records straight from DNS.
# Check MX records (where mail is routed)
dig MX example.com +short
# Check the SPF / any TXT record at the root
dig TXT example.com +short
# Check a DKIM key (selector + ._domainkey + domain)
dig TXT google._domainkey.example.com +short
# Check DMARC (always at _dmarc)
dig TXT _dmarc.example.com +short
# Check an SES DKIM CNAME
dig CNAME abc123._domainkey.example.com +short
# Check which nameservers a domain is delegated to
dig NS example.com +shortIf a query returns nothing, the record is missing, not yet propagated, or published at the wrong host (a classic cause: you edited DNS at your registrar while your nameservers point at a different DNS host, so your edits are ignored). Cross-check with at least two web tools, since some checkers parse headers inconsistently.
A Setup Checklist and Common Failures
A clean mail setup, in order:
- Confirm delegation.
dig NS yourdomain.comshould show your intended DNS host's nameservers. If not, fix it at the registrar first; nothing else works until this is right. - Add MX for whoever receives your mail. Exactly one mail destination; never split MX across two providers.
- Add one SPF TXT, merging every sending service into a single record, staying under 10 lookups, ending in
~all(then-allonce stable). - Add DKIM for each sender (the selector TXT or CNAME they give you), and on Cloudflare keep verification CNAMEs grey-clouded.
- Add DMARC at
_dmarc, starting atp=nonewith aruareporting address. - Verify each record with
dig, then move DMARC towardp=rejectonce reports show all legitimate senders aligned.
The failures you will most likely hit, and their causes:
- Mail goes to spam: usually missing or failing SPF/DKIM, or DMARC not aligned. Check the message headers for
spf=pass,dkim=pass,dmarc=pass. - DKIM not verifying: wrong record name (double-appended domain or stripped underscore), proxied CNAME on Cloudflare, or simply not propagated yet.
- SPF permerror: more than 10 DNS lookups, or two SPF records existing at once. Merge into one and trim includes.
- Spoofed mail still getting through: DMARC stuck at
p=none, or no DMARC at all. Move toquarantinethenreject. - Edits seem to do nothing: your nameservers point at a different DNS host than the one you are editing. Fix delegation.
Related
Node.js Memory, Garbage Collection & Production Failures
How Node.js memory really works: the V8 heap, garbage collection, memory leaks, OOM crashes, and diagnosing it all in production on EC2 and ECS.
Authentication and Authorization, Explained: The Interview-Ready Deep Dive
A beginner-to-advanced guide to authentication and authorization: password hashing, sessions vs JWTs, access and refresh tokens, OAuth 2.1, and passkeys.
API Integration in JavaScript: Reading Responses, Handling Errors, and Stripe
Read API responses the right way: res.json() vs res.text(), error handling, timeouts, retries, React data fetching, and real Stripe payments and webhooks.