Emails usually go to spam for one of four reasons: authentication is missing or not aligned (SPF, DKIM, DMARC); the sending infrastructure is off (no proper reverse DNS, a real blocklist listing, an IPv6 gap); the domain or IP has little or poor reputation; or recipients aren't engaging and some are complaining. Check them in that order. Each step below is a check you can run in a few minutes.

If you would rather hand it over, our Deliverability Fix is exactly this checklist done for you on one domain, with a written report.

Quick triage: match the symptom to the step

What you see Most likely area Start at
Everything goes to spam, everywhere, suddenly Broken DNS record, blocklisting Steps 2–6
Spam at one provider only That provider's view of your reputation Steps 7–8
Some messages fine, others in spam IPv6 gap, one sender not authenticated, or content Steps 4, 5, 9
New domain or new server, everything passes No reputation yet Step 7
Marketing mail in spam, receipts fine Engagement, complaints, unsubscribe Step 8
Messages bounce instead of landing in spam Real rejection; read the bounce text Steps 2–6

A bounce is more useful than a spam-folder placement, because the receiver tells you why. Read the full text of the rejection: it often names the failing check or links to the provider's documentation.

Step 1: Read the headers of a message that went to spam

Send a message to a Gmail account you control. If it lands in Spam, open it, click the three dots and choose Show original. The summary at the top shows SPF, DKIM and DMARC results. The raw headers have the details:

Authentication-Results: mx.google.com;
       dkim=pass header.i=@example.com header.s=mail;
       spf=pass smtp.mailfrom=example.com;
       dmarc=pass (p=QUARANTINE) header.from=example.com

Gmail also shows a yellow banner explaining why it chose Spam. "Similar to messages identified as spam in the past" points to reputation, not configuration.

Also send one to the address mail-tester.com gives you, and one to port25's verifier at check-auth@verifier.port25.com, which replies with a full SPF, DKIM and iprev report.

Step 2: Check SPF

dig +short TXT example.com
  • Exactly one record starting with v=spf1. Two records is a permerror.
  • Every service that sends as you is included.
  • No more than 10 DNS lookups in total. Over 10 is also a permerror; see SPF too many DNS lookups.

Full walkthrough: how to set up an SPF record.

Step 3: Check DKIM

Find the selector in the s= tag of the DKIM-Signature header, then:

dig +short TXT mail._domainkey.example.com
  • Exactly one record. A duplicate gives "multiple DNS replies" and DKIM fails; we did this to ourselves once.
  • The d= domain in the signature is your domain, not your provider's.
  • The key is not truncated.

See how to set up DKIM.

Step 4: Check DMARC and alignment

dig +short TXT _dmarc.example.com
  • One record at _dmarc, starting with v=DMARC1.
  • An rua address, so you get reports.
  • In the headers, header.from matches the domain that passed SPF (smtp.mailfrom) or DKIM (header.i).

A classic failure: SPF and DKIM both pass, but for the provider's domain, so DMARC fails for yours. How to set up DMARC explains alignment.

Step 5: Check reverse DNS and HELO

Find the sending IP in the Received: headers or the port25 report. Then:

dig +short -x 203.0.113.10
dig +short A mail.example.com

The PTR should be a real mail hostname that resolves back to the same IP, and it should match the name your server uses in HELO. If your server also has IPv6, make sure IPv6 has a PTR too, or send over IPv4 only. Details: reverse DNS for email. If you use a hosted provider on shared IPs, this is their job.

Step 6: Check blocklists, carefully

Real listings matter; false alarms waste days. To query Spamhaus for 203.0.113.10, reverse the octets:

dig +short 10.113.0.203.zen.spamhaus.org
  • No answer means not listed.
  • 127.0.0.2 to 127.0.0.11 are real listings; look the IP up on Spamhaus's site for the reason and removal steps.
  • 127.255.255.x means Spamhaus refused the query, usually because it came through a public resolver such as 8.8.8.8 or 1.1.1.1. It is not a listing, but many naive checkers report it as one.

Also: UCEPROTECT level 3 lists whole provider networks (for example, all of OVH). That is not a listing of your IP.

Step 7: Check reputation and warm-up

If everything above passes and mail still goes to spam, the problem is almost always reputation:

  • New or dormant domain or IP? It has no history. On day one we sent two near-identical test emails from two of our domains to Gmail; one went to the Inbox and the other to Spam, with authentication passing on both. Follow an IP warm-up schedule.
  • Sudden volume jumps? Doubling overnight can look like a compromised account.
  • Shared IP with bad neighbours? On some providers' shared pools, other senders affect you. See shared vs dedicated IPs.

If you send to Gmail at volume, sign up for Google Postmaster Tools and check domain reputation and spam rate.

Step 8: Check the list and engagement

  • Complaints. Gmail requires bulk senders to keep complaints under 0.3%; aim for under 0.1%.
  • Unsubscribe. Marketing mail needs a one-click unsubscribe. If unsubscribing is harder than pressing "Report spam", people press "Report spam".
  • Old addresses. Remove hard bounces immediately and stop mailing people who have not opened in months.
  • Consent. Purchased or scraped lists hurt reputation quickly.

Bulk senders should check every item on the Gmail and Yahoo bulk sender requirements.

Step 9: Check the content last

Content is rarely the main cause any more, but these still hurt:

  • Link text that shows one domain and links to another.
  • URL shorteners, or links to domains with poor reputation.
  • Image-only messages with almost no text.
  • A From name or subject that does not match the content.
  • Attachments from a new sender.
  • A Reply-To on a different, unrelated domain from the From address.

A plain message with a clear subject, a couple of links to your own domain and a visible unsubscribe for marketing mail rarely has a content problem. If you are unsure, send the same text with a neutral test subject to mail-tester.com and compare the scores.

Step 10: Ask what changed

When mail that used to reach the inbox suddenly starts landing in spam, something usually changed. Before digging deeper, list everything that happened in the last few weeks:

  • A DNS provider move, where records were copied by hand and one was missed or mangled.
  • A new tool that sends as your domain and was never added to SPF or given DKIM.
  • A provider change, or a provider moving you to a different IP pool.
  • A new type of mail, a big import of contacts, or a sudden campaign.
  • A password leak or a compromised account sending on your behalf.

DMARC aggregate reports are a quick way to spot a new or unknown sender, because they list every IP sending as your domain.

If you run your own mail server

Your logs show exactly what each receiver said. On Ubuntu with Postfix:

# Recent deliveries to Gmail, with the response
sudo grep 'to=<.*@gmail.com>' /var/log/mail.log | tail -n 20

# Anything deferred or bounced, with the reason
sudo grep -E 'status=(deferred|bounced)' /var/log/mail.log | tail -n 20

status=sent (250 ...) only means the receiver accepted the message, not that it reached the inbox. A 4xx deferral that mentions rate limits or unusual traffic means you are sending faster than your reputation allows. Also confirm your server is not an open relay and that every login can only send as its own addresses, so a leaked password cannot damage your reputation. Our self-hosted email server guide covers both.

If you use a hosted provider

With SendGrid, Mailgun, Resend, Postmark or similar, the provider handles reverse DNS and IP reputation on shared pools. Your part is domain authentication (custom DKIM and, ideally, a custom return path so SPF aligns), list hygiene and complaint rates. Check the provider's suppression list and bounce logs too: they often show that a receiver has been deferring or rejecting your mail for days.

Common mistakes

  • Fixing content first. Rewriting copy for a week when the real problem is a duplicate DKIM record.
  • Trusting one checker's "listed" result. Verify Spamhaus answers yourself; ignore UCEPROTECT level 3.
  • Adding a second SPF record for a new tool instead of merging it into the existing one.
  • Testing only with one Gmail account. Test Gmail, Outlook and Yahoo; they disagree.
  • Changing several things at once. Change one thing, retest, then move on.

How to verify it worked

After each fix:

dig +short TXT example.com
dig +short TXT mail._domainkey.example.com
dig +short TXT _dmarc.example.com
dig +short -x 203.0.113.10

Then resend to port25's verifier and to mail-tester.com, and to accounts at Gmail, Outlook and Yahoo. If you run your own server, swaks makes repeat tests quick:

swaks --to check-auth@verifier.port25.com --from hello@example.com \
  --server mail.example.com --port 587 --tls \
  --auth LOGIN --auth-user hello@example.com

Our free email checker runs the DNS checks above for any domain. If you have worked through the list and are still stuck, the Deliverability Fix covers SPF, DKIM, DMARC and PTR on whatever provider you use; prices are on the pricing page.