Email Deliverability for Self-Hosted Supabase: SPF, DKIM, DMARC

Stop self-hosted Supabase auth emails landing in spam. A practical guide to SPF, DKIM, DMARC, domain reputation, and inbox testing.

Cover Image for Email Deliverability for Self-Hosted Supabase: SPF, DKIM, DMARC

You wired up custom SMTP, sent a test signup, and the confirmation email never showed up. Or worse — it landed in spam, and you only found out when a paying customer emailed support asking why they couldn't verify their account. This is one of the most common and most frustrating problems for anyone running self-hosted Supabase: the auth flow works perfectly in your logs, but the emails quietly die in spam filters.

The fix almost never lives inside Supabase. It lives in your DNS records and your sending domain's reputation. This guide walks through SPF, DKIM, and DMARC — the three DNS records that decide whether your transactional emails reach the inbox — plus the domain-reputation traps specific to self-hosting. If you haven't set up SMTP yet, start with our SMTP and email templates guide first, then come back here to make those emails actually deliverable.

Why Self-Hosted Auth Emails End Up in Spam

By default, the self-hosted Supabase stack ships with Inbucket (or the newer Mailpit), a local SMTP catch-all meant for development. It captures emails so you can view them in a browser — it never sends anything to the real world. Plenty of self-hosters deploy to production, never swap this out, and wonder why no email ever arrives. Step one is always to point GoTrue at a real SMTP provider.

But once you do that, a second wall appears. Mailbox providers — Gmail, Outlook, Apple Mail — assume unauthenticated email is a phishing attempt. As of 2024, Gmail and Yahoo require SPF, DKIM, and DMARC for bulk senders, and the trend has only tightened since. If your [email protected] address has none of these records, your password resets and magic links are treated as suspicious by default.

The community pain is well documented. A long-standing Supabase issue tracks signup emails being flagged as spam, and the consensus fix is always the same: authenticate your sending domain and stop relying on shared infrastructure. Supabase's own SMTP docs put it bluntly — work with your email provider to configure DKIM, DMARC, and SPF, because that's what moves deliverability.

SPF: Authorize Who Can Send for You

SPF (Sender Policy Framework) is a single TXT record listing which servers are allowed to send email on behalf of your domain. When Gmail receives a message claiming to be from yourapp.com, it checks this record to confirm the sending server is authorized.

If you send through a provider like Resend, Postmark, AWS SES, or Mailgun, they publish an include value for you:

; TXT record on yourapp.com
v=spf1 include:_spf.resend.com ~all

Three things trip people up here:

  • One SPF record per domain. If you already have an SPF record for another service, merge the include into the existing one — don't add a second TXT record. Two SPF records is itself a failure.
  • ~all vs -all. ~all (softfail) is forgiving while you test; -all (hardfail) is stricter and better once you're confident. Start soft, tighten later.
  • The 10-lookup limit. SPF allows only 10 DNS lookups. Stacking many includes blows past it and silently breaks SPF. Keep your sending stack lean.

SPF alone isn't enough — it breaks when email is forwarded — but it's the foundation the other two records build on.

DKIM: Cryptographically Sign Your Mail

DKIM (DomainKeys Identified Mail) attaches a cryptographic signature to every outgoing message. The receiving server fetches your public key from DNS and verifies the signature, proving the email genuinely came from your domain and wasn't tampered with in transit.

Your SMTP provider generates a key pair and gives you a CNAME or TXT record to publish, usually on a selector subdomain:

; CNAME record
resend._domainkey.yourapp.com  ->  resend._domainkey.resend.com

DKIM is the single most important signal for transactional mail because, unlike SPF, it survives forwarding. The signature travels with the message. Once your provider reports the DKIM status as "verified," you've cleared the hardest deliverability bar.

A practical tip for self-hosters running multiple projects: use a dedicated subdomain for auth mail, like auth.yourapp.com or mail.yourapp.com. This isolates the reputation of your transactional email from your root domain, so a marketing misfire can't poison your password-reset deliverability. It pairs naturally with the custom domain setup you've likely already done for your Supabase API.

DMARC: Tie It Together and Get Reports

DMARC (Domain-based Message Authentication, Reporting & Conformance) tells receiving servers what to do when SPF or DKIM fails, and — crucially — sends you reports on who is sending mail as your domain.

Start in monitoring mode so you don't accidentally block your own legitimate mail:

; TXT record on _dmarc.yourapp.com
v=DMARC1; p=none; rua=mailto:[email protected]; fo=1

p=none means "don't reject anything yet, just report." Watch the aggregate reports (the rua address) for a week or two to confirm your real auth emails pass alignment — meaning the domain in the From: header matches the domain that SPF and DKIM authenticated. Once everything aligns cleanly, tighten the policy:

v=DMARC1; p=quarantine; rua=mailto:[email protected]

…and eventually p=reject. A published DMARC record at p=quarantine or stronger is itself a positive reputation signal — it tells Gmail you take domain security seriously.

RecordWhat it provesWhere it lives
SPFServer is authorized to sendyourapp.com TXT
DKIMMessage is signed and untamperedselector._domainkey CNAME/TXT
DMARCPolicy + reporting on failures_dmarc.yourapp.com TXT

Domain Reputation: The Part DNS Can't Fix

Even with all three records perfect, a brand-new domain has no sending history, and mailbox providers are cautious with unknown senders. A few habits that matter, drawn directly from community guidance and provider best practices:

  • Separate auth mail from marketing. Send password resets and confirmations through one provider/subdomain and newsletters through another. If your marketing list earns spam complaints, you don't want it dragging your magic-link deliverability down with it. This is the single most-repeated piece of advice in deliverability circles.
  • Don't use shared/default sending infrastructure for production. Sharing an IP pool means inheriting other senders' spam problems. A dedicated or reputable provider gives you a clean reputation to build on.
  • Keep transactional content plain. Heavy images, link shorteners, and promotional language ("FREE!", "ACT NOW") trip content filters. Auth emails should be short, plain, and obviously functional. You control this through your email templates.
  • Warm up gradually. If you expect volume, ramp it. A domain that suddenly sends thousands of emails on day one looks like a compromised account.

It's also worth reducing how many emails you send in the first place. If a chunk of your auth flow is confirmation emails, consider whether magic links or OAuth providers cover some of those journeys — fewer transactional sends means fewer chances to land in spam and a cleaner reputation overall.

Test Before You Trust

Never assume — verify. Three checks before you call it done:

  1. Send a real signup to a Gmail and an Outlook account. These two are the strictest and the most common. If they pass, most others follow.
  2. Use a seed-test tool like mail-tester.com. Send a test email to the address it gives you and it scores your SPF, DKIM, DMARC, and content out of 10. Aim for 9+.
  3. Check the raw headers of a received email for dkim=pass, spf=pass, and dmarc=pass. All three passing with alignment is the goal.

If something fails, the headers tell you exactly which record is the problem — far faster than guessing.

Where Supascale Fits

None of this is conceptually hard, but it's fiddly, easy to misconfigure, and painful to debug when an email silently vanishes. Supascale is built to remove that friction from running self-hosted Supabase. It manages your custom domains with free SSL and gives you a clean UI for auth provider and SMTP configuration — so wiring a real sending domain into GoTrue is a form, not a hunt through environment variables and a container restart.

Pairing that with OAuth and magic-link flows configured through the same dashboard means you can lean on fewer password-based email sends, reducing your deliverability surface area from day one. And because Supascale is a one-time purchase for unlimited projects, you can give each project its own properly-authenticated sending subdomain without per-project pricing pressure.

Conclusion

Self-hosted Supabase auth emails land in spam for one reason above all others: an unauthenticated sending domain. Publish a clean SPF record, verify DKIM on a dedicated subdomain, and roll out DMARC from p=none toward p=reject while watching the reports. Keep auth mail separate from marketing, keep the content plain, and always seed-test against Gmail and Outlook before you ship. Do that, and the confirmation emails that used to vanish will reliably hit the inbox.

Ready to stop fighting environment variables and DNS in the dark? Get started with Supascale and manage your domains, SSL, and auth configuration from one place.

Further Reading