# Email Deliverability Deep-Dive: SPF, DKIM, DMARC, BIMI on Cloudflare DNS
TL;DR
Your legitimate emails end up in spam because your DNS records aren't configured correctly. This guide walks through SPF, DKIM, DMARC, BIMI and MTA-STS — the five email authentication layers — with specific Cloudflare DNS steps. Done right, your inbox placement jumps from 60% to 95%+.
## Why emails land in spam
Since 2024, Gmail and Yahoo require senders sending >5,000 messages/day to have:
- SPF record published
- DKIM signature (aligned)
- DMARC policy with `p=none` at minimum
- One-click unsubscribe for bulk mail
Apple, Outlook, and major ISPs apply similar rules. Non-compliant = spam folder.
## The five layers
| Layer | Purpose | DNS record | Priority |
| SPF | Who is allowed to send | TXT | Must have |
| DKIM | Cryptographic signature | TXT | Must have |
| DMARC | What to do when SPF/DKIM fails | TXT | Must have |
| MTA-STS | Force TLS on incoming mail | TXT + HTTPS | Nice to have |
| BIMI | Logo in inbox | TXT + SVG | Nice to have |
## Step 1 — SPF (Sender Policy Framework)
Declares which servers can send email as you.
Example for a domain using Google Workspace + Razorpay for transactional + Mailgun:
```
v=spf1 include:_spf.google.com include:spf.razorpay.com include:mailgun.org ~all
```
Add to Cloudflare DNS:
1
Cloudflare Dashboard → Your Domain → DNS → Records
Key rules:
- Only **one** SPF record per domain. Multiple = broken. Merge includes into one.
- `~all` (soft-fail) is standard. `-all` (hard-fail) is strict but can cause legit mail to bounce.
- Max 10 DNS lookups (includes count). Use `spf-flatten` tools if you exceed.
Verify:
```bash
dig TXT yourcompany.com +short
# should return: "v=spf1 include:_spf.google.com ~all"
# Or use mxtoolbox.com/spf.aspx
```
## Step 2 — DKIM (DomainKeys Identified Mail)
Every outgoing email gets signed with a private key. Recipient verifies via your public key in DNS.
### For Google Workspace
1
Google Admin Console → Apps → Google Workspace → Gmail → Authenticate Email
2
Click "Generate new record" (2048-bit)
3
Copy the TXT record provided:
4
Add to Cloudflare DNS as TXT record
5
Wait 10 minutes, click "Start authentication" in Google Admin
### For Mailgun / SendGrid / AWS SES
Each gives you similar instructions. Typically 3 TXT records — add all three to Cloudflare.
### For Postfix/Exim (self-hosted)
On your VPS:
```bash
sudo apt install opendkim opendkim-tools
sudo mkdir -p /etc/opendkim/keys/yourcompany.com
cd /etc/opendkim/keys/yourcompany.com
sudo opendkim-genkey -s default -d yourcompany.com
sudo cat default.txt
# Output: "default._domainkey IN TXT (..."
```
Add the value as TXT record in Cloudflare. Configure Postfix to sign outbound mail (see [DomainIndia SMTP tutorial](https://domainindia.com/support/kb/category/email-hosting)).
Verify:
```bash
dig TXT default._domainkey.yourcompany.com +short
```
Send a test email to your Gmail, check **Show original**: should say "DKIM: PASS".
## Step 3 — DMARC (Domain-based Message Authentication)
The policy that tells recipient what to do when SPF or DKIM fails.
Start in monitor mode:
```
_dmarc.yourcompany.com TXT "v=DMARC1; p=none; rua=mailto:
[email protected]; ruf=mailto:
[email protected]; pct=100"
```
Meaning:
- `p=none` — just monitor, don't reject
- `rua` — send aggregate reports here (daily summaries from receivers)
- `ruf` — send forensic reports (individual failures)
- `pct=100` — apply to all mail
Run `p=none` for 2-4 weeks. Reports tell you which senders are passing/failing. Use tools like [Valimail, Postmark, dmarcly.com] (many have free tiers) to parse XML reports.
Once all legit senders pass, upgrade:
```
_dmarc.yourcompany.com TXT "v=DMARC1; p=quarantine; pct=100; rua=mailto:
[email protected]"
```
- `p=quarantine` — send to spam folder on fail
- Eventually → `p=reject` — bounce the mail
Warning
Don't start at p=reject. If your SPF/DKIM isn't perfect, legit emails bounce. Walk through none → quarantine → reject over weeks, monitoring reports.
## Step 4 — MTA-STS (Mail Transfer Agent Strict Transport Security)
Forces TLS on incoming mail. Prevents downgrade attacks.
Two DNS records + one HTTPS file:
**TXT record:**
```
_mta-sts.yourcompany.com TXT "v=STSv1; id=20260424000000"
```
**MTA-STS policy TXT:**
```
_smtp._tls.yourcompany.com TXT "v=TLSRPTv1; rua=mailto:
[email protected]"
```
**Policy file at `https://mta-sts.yourcompany.com/.well-known/mta-sts.txt`:**
```
version: STSv1
mode: enforce
mx: *.google.com
mx: *.googlemail.com
max_age: 86400
```
Create `mta-sts.yourcompany.com` as a Cloudflare CNAME pointing to your web server serving this file. Or use Cloudflare Workers to serve it statically.
## Step 5 — BIMI (Brand Indicators for Message Identification)
Display your logo next to emails in Gmail / Yahoo / Apple Mail inbox.
Requirements:
- DMARC with `p=quarantine` or `p=reject` (minimum)
- SVG logo following BIMI SVG Tiny PS spec
- (Optional but recommended) VMC (Verified Mark Certificate) from DigiCert or Entrust — paid ($1,000+/yr)
```
default._bimi.yourcompany.com TXT "v=BIMI1; l=https://yourcompany.com/bimi/logo.svg; a=https://yourcompany.com/bimi/vmc.pem"
```
- `l=` — URL to SVG logo
- `a=` — VMC certificate (only if you have one)
Without VMC, Gmail shows only verified brands. Small businesses: BIMI works in Yahoo/Apple but not Gmail (without VMC).
## Practical configuration — real example
A small SaaS on DomainIndia + Google Workspace + Razorpay + Cloudflare DNS:
```
# SPF — apex
@ TXT "v=spf1 include:_spf.google.com include:spf.razorpay.com ~all"
# DKIM — from Google Workspace
google._domainkey TXT "v=DKIM1; k=rsa; p=MIIBIjAN..."
# DKIM — from Razorpay
razorpay._domainkey TXT "v=DKIM1; k=rsa; p=MIIBI..."
# DMARC
_dmarc TXT "v=DMARC1; p=quarantine; pct=100; rua=mailto:
[email protected]"
```
## Monitoring deliverability
Tools:
- **Google Postmaster Tools** (postmaster.google.com) — daily inbox placement, spam rate, DMARC authentication rate for Gmail
- **MXToolbox** (mxtoolbox.com) — health check of all DNS records
- **Mail-Tester** (mail-tester.com) — send an email to their unique address, get a 0-10 score with detailed report
- **Valimail / Dmarcly** — parse DMARC reports for you
Target metrics:
- Spam rate (Postmaster) < 0.10% (hard cap is 0.30% in 2024 Google rules)
- DMARC authentication rate > 98%
- Mail-Tester score ≥ 9/10
## Transactional vs marketing — keep them separate
Send transactional mail (order receipts) from `
[email protected]` or `
[email protected]`. Marketing mail (newsletters) from `
[email protected]`. Using a subdomain (`mail.yourcompany.com`) for marketing isolates reputation so marketing problems don't hurt transactional delivery.
## Handling bounces + complaints
Log bounces from your email provider's webhook. Unsubscribe + suppress hard-bounced addresses. Respect complaint feedback (List-Unsubscribe, spam reports).
Bounce > 5% = reputation damage fast. Clean your list regularly.
## Common pitfalls
## FAQ
Q
Can I skip BIMI and MTA-STS?
Yes — SPF + DKIM + DMARC are the mandatory 3. BIMI is cosmetic (logo in inbox). MTA-STS helps but only matters if you're worried about state-level TLS downgrades.
Q
Does Cloudflare Email Routing help deliverability?
Cloudflare forwards email to your actual provider. Deliverability depends on the provider's SPF/DKIM, not Cloudflare's. But Cloudflare does let you easily add MX records and workers for auto-replies.
Q
What if my domain uses DomainIndia email hosting?
Our webmail setup auto-configures SPF + DKIM. For custom TXT records (DMARC, BIMI, MTA-STS), add via cPanel → Zone Editor.
Q
Reports flooding my inbox — help?
Use a tool like Postmark's DMARC Weekly Digest (free) or dmarcly.com. They aggregate XML into weekly summaries.
Q
Gmail vs Yahoo vs Outlook — do I tune differently?
SPF/DKIM/DMARC are universal. Gmail applies stricter volume rules (if you send >5K/day). Outlook cares more about IP reputation. Test across all three.