Why Cold Emails Land in Spam (and the Order You Have to Fix It In)

You are probably fixing the last thing first
When email starts landing in spam, the reflex is to rewrite it. Shorter subject line. Fewer links. Remove the word "free". Try a different opening.
Content is real, but it is the last 20% of the problem. Ahead of it sit two things that are almost entirely mechanical, and if either is broken then no amount of rewriting will help — because your message is losing the delivery decision before a filter has read a word of it.
The order is authenticate, warm up, clean the list, then write. Here is what each step actually involves.
Part 1 — Authentication
Three DNS records. Gmail and Yahoo both require all three from bulk senders, and missing any one means every message starts behind.
SPF — and the limit that breaks it later
SPF is a TXT record listing which servers may send as you:
v=spf1 include:_spf.google.com ~all
You may have exactly one SPF record. Two is a permanent error and SPF fails entirely — receivers do not merge them. Adding a new sending service means editing the existing record, never adding a second.
But the rule that catches people months later is the 10 DNS lookup
limit. Every include, a, mx,
ptr, exists and redirect counts — and
includes nest, so a single include: can consume four lookups on its
own.
Cross ten and receivers return permerror, which fails SPF for
every message you send. The insidious part is the timing: it does not
break when you set the record up. It breaks the day you add one more tool, months
later, when nobody is looking at DNS.
DKIM — and why empty selectors are fine
Your provider publishes a public key at
selector._domainkey.yourdomain.com and signs outgoing mail with the
private half.
You need to know your selector, and it is provider-specific: Google uses
google, Microsoft uses selector1 and
selector2, Hostinger uses hostingermail-a.
Empty selectors are normal. Many hosts publish spare
selectors with an empty p= value ready for rotation, and an empty
p= is also how a key is revoked. "One selector with a key, two empty"
is a correctly configured domain — not a fault. Only "no selector has a key" is a
problem.
DMARC — start at none, and read the reports
_dmarc.yourdomain.com TXT "v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com"
p=none changes nothing about delivery. What it does is start the
aggregate reports flowing, and those reports are the only way to discover that
your invoicing tool has been failing DKIM for a year.
Without rua= you are blind. And going straight to
p=reject before reading reports is how people accidentally block
their own accounting software.
Part 2 — Warmup, and the mistake that wastes weeks
A new domain sending 500 messages on day one is a spam signal regardless of content. Reputation is built on consistency, and receivers score the shape of your sending as much as the volume.
A domain that sends 10, then 10, then 400 looks compromised. One that multiplies by roughly 1.2 a day looks like a business growing.
The cap is domain-wide, not per mailbox
This is the mistake that wastes the most time. Four mailboxes on one domain do not get four separate allowances. Receivers score the sending domain, so splitting the same volume across mailboxes fools nobody.
Day one is ten emails across all mailboxes, not ten each. Separate domains are the legitimate way to scale — and each one needs its own warmup from zero.
Four rules that matter more than the numbers
- Weekdays only during warmup. A domain sending on Sunday at Tuesday's rate looks automated.
- Spread sends across hours. Everything in one minute is the clearest bot signal there is.
- Stop at 5% bounces. Continuing through a high bounce rate is what gets a domain blocked — not the volume itself.
- Replies are the strongest positive signal. Ten emails that get two replies beat a hundred that get none.
Part 3 — Bounces, and the code that fools everyone
Only hard bounces should suppress an address permanently. Getting this wrong costs money in both directions: suppress a soft bounce and you delete a reachable contact who was on holiday; keep mailing a hard bounce and you get the domain blocked.
Read the RFC 3463 status code rather than guessing from the prose:
| Code | Means | Do |
|---|---|---|
| 5.1.1 | Mailbox does not exist | Suppress permanently |
| 5.1.2 | Domain does not exist | Suppress permanently |
| 5.2.2 | Mailbox full | Retry — the address is real |
| 5.7.1 | Blocked by policy | Retry — your reputation, not their address |
| 5.7.26 | Failed authentication | Fix your DNS. Suppress nobody |
| 4.x.x | Any transient failure | Retry up to 3 times over 72h |
Here is the trap. 5.7.1 and 5.7.26 are 5.x.x codes, so they look permanent. They are not about the recipient at all — they mean your authentication or reputation failed. A classifier that only checks the first digit will suppress those contacts, and you will quietly delete good addresses because your own DKIM is broken.
Part 4 — the content check nobody runs
Once the mechanics are right, content matters. The things with measurable effect are trigger phrases, image-heavy bodies with little text, a high link-to-text ratio, and a missing unsubscribe.
The bug that broke a live campaign
If you rewrite links for click tracking, exclude your unsubscribe path.
A tracker that rewrites every href will happily rewrite the
unsubscribe link too, so one-click unsubscribe points at the tracker instead of
the opt-out endpoint. The recipient clicks, nothing happens, and the next step is
a spam complaint — which costs far more reputation than the click data was ever
worth.
When you are already in trouble
- Stop sending. Volume through a reputation problem deepens it.
- Check the blocklists that matter. Spamhaus ZEN blocks mail at most large providers; SORBS is largely informational. Treat them differently.
- Find the cause before requesting delisting. Delisting without a fix gets you relisted, and repeat listings are harder to clear.
- Resume at 20% of previous volume and ramp again.
Recovery takes weeks, not days. There is no button.
Frequently asked questions
Why do my cold emails go to spam?
Most often because of missing or broken authentication, then a sending domain with no reputation, then a list with a high bounce rate — and only then the content. Gmail and Yahoo require SPF, DKIM and DMARC from bulk senders, so missing any one means every message starts the delivery decision at a disadvantage. Fix them in that order; rewriting the subject line while DMARC does not exist changes nothing.
What is the SPF 10 lookup limit?
SPF permits a maximum of ten DNS lookups when a receiver evaluates your record. Every include, a, mx, ptr, exists and redirect counts, and includes nest, so one include can use four lookups by itself. Cross ten and receivers return a permanent error that fails SPF for every message. It typically breaks months after setup, on the day you add one more sending tool.
How long does email warmup take?
Around 30 days to reach 100 messages a day from a standing start, ramping geometrically rather than in fixed steps. The exact numbers matter less than consistency: send on weekdays only, spread messages across hours rather than firing them in one minute, and stop entirely if the bounce rate passes five per cent. Continuing through a high bounce rate is what gets a domain blocked.
Do multiple mailboxes let me send more during warmup?
No, and this is the most expensive misunderstanding in cold email. Reputation attaches to the sending domain, so four mailboxes on one domain share one allowance rather than getting four. Day one is ten messages across all of them. Separate domains are the legitimate way to scale, and each needs its own warmup from zero.
What is the difference between a hard and soft bounce?
A hard bounce is permanent — the mailbox or domain does not exist — so suppress the address forever. A soft bounce is transient, such as a full mailbox, so retry a few times before suppressing. The trap is that 5.7.1 and 5.7.26 look permanent because they begin with five, but they mean your own authentication or reputation failed rather than the address being dead. Suppressing on those deletes reachable contacts.
Can any tool guarantee inbox placement?
No. Receivers make their own decisions and change them without notice, so anyone promising an inbox is selling you something they cannot deliver. What you can do is remove the known, controllable causes of filtering — authentication, sending shape, list hygiene and content — which is what separates mail that has a chance from mail that never did.
The scripts that check all of this
Everything above is automated in the Email Deliverability Toolkit — five Python scripts that check your DNS with the fix printed against each failure, generate a warmup ramp, classify any bounce from its status code, run a draft through a pre-send check, and test the five blocklists that actually affect placement. Nothing to install.
Keep reading
All articles →
How to Build an Agent Loop From Scratch (It's About 100 Lines)
Every agent tutorial shows a chat completion, adds one fake tool, and ends. Then you build something real and hit the four things nobody covered.
Aug 13, 2026 · 13 min read
How to Train Your Team for an Automated Workplace
How to Train Your Team for an Automated Workplace (Without Losing Momentum) Automation is no longer a “future initiative”—it’s a competitive necessity. From inv...
Mar 18, 2026 · 11 min read
Invoice Processing Automation: From Invoice Received to Invoice Paid
The average business spends $9.40 to process one invoice; the best spend $2.78. Here is the five-stage flow that closes the gap, how invoice coding actually works, and a 90-day imp
Aug 12, 2026 · 12 min read