Email Spam Tester

Email Spam TesterBlog › Why Are My Emails Going to Spam?

Why Are My Emails Going to Spam?

A developer who reads mail headers for a living walks through the real reasons a message ends up in spam, from SPF and DKIM alignment to your own reputation.

By Serhii TanichevUpdated 8 min read

The message looked fine. A plain newsletter, decent design, a real unsubscribe link at the bottom. It had landed in the spam folder of a test mailbox, and the person who sent it wanted to know why, in the tone people use when they have already checked everything twice.

So I did what I always do. I opened the raw source and scrolled past the body to the headers. Nobody looks there, which is a shame, because the receiving server writes down most of its reasoning right at the top of the message. Authentication-Results, Received, the spam engine's own score line if it left one. That newsletter had dkim=fail in the second line, and once you see that, the pretty design stops mattering.

I have spent years running mail infrastructure for an email service provider, and I built Email Spam Tester partly because I got tired of explaining the same header block over and over. Here is the walk I take through it, in the order the receiving side takes it.

The receiver decides before it reads a word

A mailbox provider makes its first judgement on the SMTP connection, before the body arrives. Who is connecting, from which IP, claiming which hostname, on behalf of which domain. If those four answers do not fit together, the content never gets a fair hearing.

That connection is the part senders skip. They tune subject lines while the server that took their message wrote "this IP has no reverse DNS" in the log and moved on.

Authentication, and the word "alignment"

Three records do the heavy lifting. SPF (RFC 7208) is a DNS record listing which servers may send mail for your domain. DKIM (RFC 6376) is a signature over the headers and body, checked against a public key in DNS. DMARC (RFC 9989, which replaced RFC 7489 in May 2026) sits on top and asks a narrower question, whether the domain that passed SPF or DKIM matches the one the reader sees in the From line. That is alignment, and it is where most of the failures I look at actually live.

A typical one. The newsletter goes out through a sending platform. SPF passes, because the platform's servers are listed in the platform's own SPF record, and the bounce address is on the platform's domain. Fine, except that the From header says the customer's domain. SPF passed for the wrong domain, so DMARC ignores it. Whether the message survives then depends entirely on DKIM, and DKIM was signed with the platform's default key, also on the platform's domain. Two passes, zero alignment, DMARC fails. If the customer's DMARC policy says p=reject, that is the end of the story.

The fix is boring and takes ten minutes once somebody explains it. Publish the CNAME records the platform gives you so DKIM signs with your domain, and set a custom return path so SPF aligns too. I have watched this exact setup be missed by teams with proper engineers, because the platform's dashboard showed a green tick for "SPF" and nobody asked which domain the tick belonged to.

Other things I find in that header block, less often but often enough:

Every one of these shows up in the Authentication-Results header of the message you already have in your spam folder. You do not need a tool to read that line, though the tester will read it for you and quote the RFC section next to the verdict.

The infrastructure you are standing on

Say authentication is clean. The next thing a receiver weighs is where the message came from, and here is where a small sender gets punished for somebody else's habits.

Shared IP pools are the usual culprit. Your newsletter leaves through the same address as a few hundred other customers of the same platform, and the reputation of that address is the average of all of them. That average is fine most weeks, and not fine the week one of them uploads a purchased list, even though nothing in your own sending changed.

Then there is the hostname the server announces in HELO, the reverse DNS of the IP, and whether the two agree. Receivers check that the PTR record of the connecting IP resolves to a name, and that the name resolves back to the same IP. A gap between the PTR record and the forward record is one of the quietest ways to end up filtered. I see it on self-hosted servers constantly, because the hosting provider set the PTR to something like static-198-51-100-7.provider.net and nobody changed it.

Blocklists sit in the same layer, Spamhaus and Spamcop and a handful of smaller ones that receivers consult on every connection. Being listed on one of the serious ones is often a hard refusal at the SMTP level rather than a small penalty, and the interesting detail is that you are frequently not listed for anything you did. The previous holder of the IP did it. Or a neighbour on the same /24.

New domains have a version of this problem too. A domain registered on Monday sending three thousand messages on Tuesday looks like exactly what it usually is. Age and a slow ramp matter more than any content rule.

The message itself

Only now does content get a turn, and I want to be honest about the size of its turn. It is smaller than people think, and larger than zero.

Filters like SpamAssassin add up small penalties from many rules, and the message is treated as spam once the total crosses a threshold, which is 5 by default. No single rule usually gets you there. Eleven of them do. An image with almost no text around it. A subject in capitals with two exclamation marks. Links whose visible text says one domain and whose href says another. A URL shortener that a spammer burned last month. HTML that was pasted out of a word processor and carries three hundred lines of styling for two paragraphs of text.

The thing I keep coming back to is that none of those are visible from the design view of a campaign editor. You have to look at the source, or run the message through an engine that does.

Engagement, which you cannot see at all

Gmail and the other large providers watch what recipients do. Opens, replies, deletions without reading, the "report spam" button, moving a message out of spam by hand. This is the part of reputation that no header will show you, and it moves slowly in both directions.

The practical consequence is that a list that has not been mailed in a year is a liability. Half of it will be dead addresses, some of which have quietly become spam traps, and the live half has forgotten who you are. The complaint rate on that first send decides your reputation for the next month.

The receiver's own rules, which changed

Since February 2024, Gmail and Yahoo enforce a published set of requirements for anyone sending in bulk, roughly five thousand messages a day to their users. Authentication with both SPF and DKIM, a DMARC record on the From domain, alignment, a one-click unsubscribe header per RFC 8058, and a spam complaint rate that stays under 0.3% as measured in Google Postmaster Tools. None of that is optional, and messages that miss it get rate limited or rejected with a response that says so. Outlook.com joined in May 2025 with its own version for the same five thousand a day: SPF and DKIM must pass, DMARC must exist at p=none or stricter and align with one of them. Mail that falls short goes to Junk first, and later can be refused outright with 550 5.7.515.

I still meet senders who have never opened Postmaster Tools. It is free, it takes a DNS record to verify your domain, and it is the only place where Gmail tells you what it thinks of you in its own numbers.

What I actually check, in order

When a message is in spam and I have twenty minutes, this is the sequence.

  1. Read Authentication-Results on the message that landed in spam. SPF, DKIM, DMARC, and for each of them, which domain. Alignment first.
  2. Look at the connecting IP in the last Received header. Reverse DNS, forward confirmation, blocklist status.
  3. Check the sending domain's age and its DMARC policy, and whether DMARC reports go anywhere a human reads.
  4. Only then open the content. Text to image ratio, link domains, the unsubscribe headers.
  5. Open Postmaster Tools, or the equivalent at the provider you are failing at, and look at the complaint rate for the last thirty days.

Most of the time the answer is in step one or two. When I built the tester, that ordering went straight into how the report is laid out, because the checks near the top are the ones that kill a message outright and the ones near the bottom only nudge it. The documentation lists all of them with what each costs.

One more thing about that newsletter with dkim=fail. The key in DNS was fine. The platform had started including the subject line in the signature a week earlier, and a security gateway in front of the recipient's mailbox was prefixing every outside subject with [EXTERNAL] before the mailbox got to verify anything. Signature computed over one version of the message, checked against another. Nobody had touched DNS, nobody had changed the template, and the message had been going to spam for eight days.

Try it on your own email

Send one message to a disposable address and read every check in the report, RFC section and all. Free, no signup.

Run a test