Add Mailgun as a sending subdomain — mg.yourdomain.com — rather than at your apex. Everything else follows from that choice: the SPF record, the DKIM selector and the MX records all go on the subdomain, your apex SPF budget stays untouched, and application mail builds a reputation separate from the mailboxes your team sends from.
The records, on the subdomain
| Type | Host | Value |
|---|---|---|
| TXT (SPF) | mg.yourdomain.com | v=spf1 include:mailgun.org ~all |
| TXT (DKIM) | <selector>._domainkey.mg.yourdomain.com | v=DKIM1; k=rsa; p=<your key> |
| MX | mg.yourdomain.com | mxa.mailgun.org and mxb.mailgun.org, priority 10 |
| CNAME (tracking) | email.mg.yourdomain.com | mailgun.org |
The DKIM selector and public key are account-specific; take both from Mailgun's domain settings. Mailgun's default selector for older domains is smtp, but newer domains get something else, so read it rather than assuming.
Two notes on the optional records. The MX records are only needed if you want Mailgun to receive mail for that subdomain — inbound routes, parsing, or replies handled by Mailgun. If you only send, skip them; adding MX for a subdomain does not affect your apex mail either way. The tracking CNAME serves click and open tracking links from your subdomain instead of a shared Mailgun host, which is worth doing: shared link domains carry other senders' reputation.
Verify before you send anything
dig +short TXT mg.yourdomain.com dig +short TXT <selector>._domainkey.mg.yourdomain.com dig +short MX mg.yourdomain.com dig +short TXT _dmarc.yourdomain.com
The DKIM query returning nothing almost always means one of three things: your DNS panel appended the zone to the host and produced ...mg.yourdomain.com.yourdomain.com, the 2048-bit key was truncated at the 255-character TXT string limit, or you are reading your own resolver's cache — add @8.8.8.8 to check.
If the key is too long for one string, split it into multiple quoted strings inside one record. The resolver concatenates them. Creating a second TXT record instead is a different thing entirely and will not work.
SPF: what it does and does not cover
SPF authorises servers to use a domain in the SMTP envelope (MAIL FROM, which arrives as Return-Path). Its limits are worth stating plainly, because they explain most of the confusion:
- It validates the envelope, not the
Fromheader your recipient reads. - It breaks on forwarding. The forwarding server is not in your record and never can be.
- It permits a maximum of 10 DNS-querying mechanisms per evaluation, counted recursively through every
include, plus a limit of two lookups that return nothing. Exceed either and receivers returnPermError, which fails SPF for all your mail at once. - Only one
v=spf1record may exist per domain name. Two is a specification violation that disables SPF.
Putting Mailgun on mg.yourdomain.com sidesteps the lookup problem completely: that subdomain's record contains one include and nothing else, and your apex keeps its own budget for your mailbox provider.
DKIM is what carries DMARC here
Send a test and read the headers:
Return-Path: <bounce+...@mg.yourdomain.com> From: Billing <billing@mg.yourdomain.com> Authentication-Results: mx.google.com; spf=pass smtp.mailfrom=mg.yourdomain.com; dkim=pass header.i=@mg.yourdomain.com; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=mg.yourdomain.com
With the subdomain setup, both SPF and DKIM align, which is the resilient configuration — a DKIM problem still leaves you an aligned SPF pass, and forwarding still leaves you an aligned DKIM signature.
If instead you keep From: billing@yourdomain.com while sending through the subdomain, relaxed alignment (the aspf=r/adkim=r default) still passes, because mg.yourdomain.com and yourdomain.com share an organisational domain. Strict alignment (aspf=s) would fail that. This is the main reason not to switch to strict alignment casually.
DMARC and reading the reports
Publish at the apex, in monitor mode first, and set the subdomain policy explicitly once you enforce:
_dmarc.yourdomain.com TXT "v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com; fo=1"
Aggregate reports are gzipped XML, one per receiver per day, listing source IPs, volumes and per-mechanism results. What to look for once Mailgun traffic appears:
- Mailgun's sending IPs showing
dkim=passandspf=passwith your subdomain. That is the healthy state. - Mailgun IPs with
dkim=fail. Usually a rotated key or a selector you republished incorrectly. - Volume from IPs you cannot place. Most turn out to be another internal tool, not an attacker.
Reports contain no subject lines or recipients — aggregate DMARC data is deliberately privacy-preserving. If a report never arrives and rua points at a different domain, that domain must authorise it with a v=DMARC1 record at yourdomain.com._report._dmarc.<their-domain>.
The sender requirements all three big receivers now enforce
Google and Yahoo both introduced bulk-sender requirements in February 2024, and Microsoft followed with its own for consumer Outlook, Hotmail and Live addresses in 2025. The common core is the same: SPF and DKIM in place, a DMARC record of at least p=none, alignment between the authenticated domain and the From domain, one-click unsubscribe for bulk mail, valid forward and reverse DNS on sending hosts, and spam complaint rates kept low — Google publishes 0.3% as the threshold to stay under. Dedicated IPs and shared pools alike are judged on this.
What not to do
- Do not add
include:mailgun.orgto an apex record that is already near the 10-lookup limit. Use the subdomain. - Do not publish the DKIM key as two records. One record, multiple quoted strings.
- Do not add Mailgun's MX records to your apex. That would hand your inbound mail to Mailgun.
- Do not enable a shared tracking domain and then wonder why links are flagged. Serve them from your subdomain.
- Do not move to
p=rejectuntil reports show every sender aligned, and setsp=deliberately rather than letting subdomains inherit.
MailPilot warms mailboxes over OAuth or SMTP/IMAP — including Mailgun, SendGrid, Amazon SES and Postmark — checks SPF, DKIM and DMARC on the sending domain, and measures real per-provider inbox placement with a seed-inbox network, so a clean DNS report is not the last thing you hear before mail starts getting filtered.
Ready to reach the inbox every time?
Automated email warmup across real peer mailboxes. Live inbox placement monitoring. Free 7-day trial - no credit card required.
Start free trial