TL;DR. We wired up a new sending domain, ran dig txt mail.sudory.com, saw an empty SPF response, and nearly opened a ticket on ourselves. The SPF record was not missing. It was one subdomain deeper than we looked, which is exactly where modern email service providers publish it. This post walks through the mistake, why every major ESP does the same thing, and the three dig commands that actually audit an ESP setup correctly.
Sudory scans domains for SPF, DKIM, and DMARC misconfigurations. So when our own sending subdomain appeared to be missing SPF, the irony landed hard enough to write about.
The panic
During a recent rollout we migrated Supabase auth emails to Resend under mail.sudory.com. Somewhere between the third and fourth coffee, a quick audit command came back looking grim:
$ dig +short txt mail.sudory.com
(empty)No SPF record. On the sending domain. For a compliance-scanning product.
The first reaction was to file an internal bug. The second reaction, fortunately, was to open the Resend dashboard. Resend reported mail.sudory.com as Verified, with all three DNS records green and the domain ready to send. Two different answers from two different tools. One of them was wrong about something.
The correction
The records Resend asked us to publish were not on mail.sudory.com. They were on three distinct locations under it:
| Record | Host | Purpose |
|---|---|---|
| DKIM | resend._domainkey.mail.sudory.com | Signature verification for the header-From domain |
| MX | send.mail.sudory.com | Bounce routing for the envelope-sender |
| SPF (TXT) | send.mail.sudory.com | Authorise IPs to send as the envelope-sender |
Run dig txt send.mail.sudory.com and the SPF record is there, plain as daylight. Our scanner was never wrong. The person running dig asked the wrong subdomain.
Why ESPs split the subdomain
Every email has two sender addresses, not one. They usually disagree on purpose.
The header-From is what the recipient sees in their mail client: noreply@mail.sudory.com. It is the domain used for DKIM signing and for DMARC identifier alignment. It is the brand-facing surface, so ESPs keep it clean.
The Return-Path, also called the envelope sender or MAIL FROM, is the address receivers route bounces to and the domain they run SPF against. ESPs want this on their own infrastructure so bounce webhooks, complaint feedback loops, and deliverability signals stay inside their platform. Resend puts it on send.mail.sudory.com. SendGrid uses em.yourdomain.com. Postmark uses pm-bounces.yourdomain.com. Different names, identical pattern.
Drawn out, our setup looks like this:
Organizational domain sudory.com (DMARC policy lives here)
│
├─ Header-From mail.sudory.com (DKIM key lives here)
│ ↓
│ Recipient sees: noreply@mail.sudory.com
│
└─ Return-Path send.mail.sudory.com (SPF + MX for bounces live here)
↓
Receivers bounce to: bounces-...@send.mail.sudory.comSPF checks happen against the Return-Path domain. DKIM signatures verify against the domain in the d= tag of the signature, which ESPs align with the header-From. DMARC then asks a single question: do either of those two checks align with the header-From domain in the way the policy requires?
In relaxed alignment (the default), alignment means sharing an organizational domain. All three of our hosts sit under sudory.com, so relaxed alignment trivially holds. In strict alignment, the domains must match exactly, which would force the Return-Path back onto the header-From domain and break the whole reason ESPs split them in the first place. If you see aspf=s or adkim=s in your DMARC record and you use a modern ESP, your reports will be full of alignment failures and you probably want to switch to relaxed.
The full DMARC explainer in the Academy walks through the alignment modes in detail.
How to actually audit an ESP domain
Three dig commands, in order.
1. Find the envelope-sender subdomain. Your ESP's setup documentation names it. Resend uses send.<yourdomain>. SendGrid uses em<N>.<yourdomain>. Mailgun uses mg.<yourdomain>. Postmark uses pm-bounces.<yourdomain>. Once you have the name, query SPF there, not on the header-From domain:
dig +short txt send.mail.sudory.comYou should see a v=spf1 record that includes the ESP's own SPF domain and ends in ~all or -all. The SPF Academy entry covers the closing mechanisms and when to tighten from soft fail to strict fail.
2. Find the DKIM selector. Selectors vary: Resend uses resend, Google uses google, Mailchimp uses k1 and k2. The format is always <selector>._domainkey.<subdomain>. Our DKIM lives at:
dig +short txt resend._domainkey.mail.sudory.comA valid record starts with p= followed by a base64-encoded public key. The DKIM Academy entry explains key rotation and selector naming conventions.
3. Find the DMARC policy. DMARC lives on the organizational domain, not on subdomains:
dig +short txt _dmarc.sudory.comLook for p=reject (strongest), p=quarantine (middle), or p=none (monitoring only). Make sure a rua= address is present so you receive aggregate reports. If sp= is absent, the subdomain policy inherits from p= by default. That is fine for our setup. The DMARC Academy entry covers policy rollout from none to reject.
Three records, three commands, under a minute each. If any of them are missing or malformed, your domain is spoofable today.
What we got right and wrong
On the DNS side, we got the setup right the first time because Resend's verification flow is strict: the domain will not move out of the Pending state until every required record resolves. The only thing we briefly got wrong was the audit query, and the only real cost was a few minutes of embarrassment.
On the operational side, the story is less tidy. The audit surfaced several things that are not DNS but still matter for transactional email done by the book:
- TLS mode. Opportunistic accepts cleartext delivery if the receiving server does not offer TLS. Enforced refuses to deliver without TLS. For auth emails carrying magic links and recovery tokens, Enforced is the right default. See MTA-STS for the policy that receivers use to signal this back to you.
- Sender address.
noreply@is a UX anti-pattern. Any reply the user sends disappears into a black hole. Use a monitored inbox and set aReply-Toheader pointing at support. - Webhook idempotency. If the auth-email hook ever returns a 500, Supabase retries. Without deduplication on the
webhook-idheader, a retry means a duplicate email. - Bounce and complaint handling. Resend posts webhooks for hard bounces and spam complaints. Ignoring them means you keep sending to dead or hostile addresses, which hurts sender reputation over time.
- Cross-client rendering. Gmail, Apple Mail, and Outlook disagree on CSS support. Preview rendering in more than one inbox before you ship a new template.
None of that is a DNS problem. All of it is something a compliance review of your own transactional email should catch, and none of it is surfaced by a dig command.
Three questions to ask about any ESP setup
When the next onboarding wizard asks you to paste DNS records into your registrar, these three questions tell you whether the result is by the book:
- Where is SPF? On the envelope-sender subdomain. Not on the header-From.
- Where is DKIM? At
<selector>._domainkey.<subdomain>, matching the header-From. - Do they align under a common organizational domain? If yes, DMARC relaxed alignment covers you.
If all three answer cleanly, your ESP setup is sound. If any of them make you hesitate, scan your domain and the report will say where you stand. That is literally what we built. It would have saved us a minor heart attack an hour ago.
FAQ
Why is dig txt mail.mydomain.com returning no SPF record?
Because SPF belongs on the envelope-sender domain, not the header-From domain. Most modern email providers, including Resend, SendGrid, and Postmark, use a deeper subdomain like send.mail.yourdomain.com for the Return-Path and publish SPF there. Run dig txt send.mail.yourdomain.com instead.
What is the difference between the From header domain and the Return-Path domain?
The From header is what the recipient sees in their mail client. The Return-Path (also called the envelope sender, or MAIL FROM) is the address receivers use for bounce notifications and SPF checks. The two do not have to match, and with most ESPs they deliberately do not.
How does DMARC alignment work when the From and Return-Path domains differ?
DMARC has two modes. In relaxed mode (the default), both domains only need to share an organizational domain, for example sudory.com. In strict mode they must match exactly. Most ESPs use deeper subdomains precisely to stay inside relaxed alignment without forcing you into a shared domain.
Which DNS records should I check to audit an ESP setup?
Three: dig txt send.<yourdomain> for SPF on the envelope-sender subdomain, dig txt <selector>._domainkey.<yourdomain> for DKIM, and dig txt _dmarc.<organizational-domain> for DMARC. If alignment works under relaxed mode, the DMARC policy covers every subdomain beneath it.
Is it normal for SPF to be missing on the header-From subdomain?
Yes, with modern ESPs. They isolate bounce handling on a dedicated subdomain to keep your user-facing domain free of SMTP plumbing. SPF publishes on the envelope-sender subdomain because that is the domain receivers check during SMTP.