My Emails Are Landing in Spam — UI-First Diagnostic

Spam-folder placement happens for measurable reasons. Walk the Insights page, the Sending Server config, and the Test diagnostic — three UI checks isolate the cause before anyone has to look at headers.

What to check from the dashboard

Spam-folder placement isn't a single failure — it's a signal that something measurable is off about your sender setup or your audience engagement. AcelleMail's dashboard exposes the three signals receivers use to make the spam vs. inbox decision.

Open a recently sent campaign and click Insights (or Subscribers → Engagement tab):

Campaign Insights — per-recipient engagement signal

What you're reading:

  • Open rate < 5% for a list you regularly engage → recipients aren't seeing it in their inbox at all. Spam placement likely.
  • Open rate normal but click-through 0 → message rendering broken (suspicious content) or recipients are opening, scanning, and not engaging. Reputation drift.
  • High open rate but high unsubscribe + complaint rate → content mismatched to subscriber expectations. ISPs penalize this.

Open the sending server configuration

Most spam-folder cases trace back to the sending side. Settings → Sending servers → click your active server:

Sending server detail — deliverability config

Three things to verify here:

  1. Authentication status — SPF / DKIM / DMARC verification chips should all be green. Red means the receiving servers can't confirm you're authorized to send for the domain.
  2. Daily quota — if you're hitting the quota every send, sends spill over into the next day's batch. Some ISPs interpret this as bulk-spam pattern.
  3. Bounce + complaint rate (last 24h) — if either is >5%, ISPs throttle your IP. Sustained high rates push you into spam folders.

Run the test diagnostic

Inside the sending server detail, Test button sends a one-off message you can inspect:

Sending server test page — diagnostic send

Send to your own address. Open the email in Gmail / Outlook / Apple Mail.

  • Email arrived in Inbox? → sending setup is OK. The spam problem is content / recipient-side (engagement, subject lines, frequency).
  • Email arrived in Spam? → sending setup is the issue. Move to operator section.
  • Email didn't arrive at all → outright blocked. IP is on a blocklist. Operator section.

In Gmail, click the email → three-dot menu → Show original. The headers reveal:

  • Authentication-Results: ... spf=pass dkim=pass dmarc=pass (all three should pass)
  • Received-SPF and DKIM-Signature presence

If any of the three says fail or is missing, that's your fix target.

Common UI causes and the fix from the dashboard

What you see Likely cause What to do
Sending server: red SPF / DKIM / DMARC chip DNS records missing or incorrect Click Verify → AcelleMail walks you through the DNS records to add. Re-verify after publishing.
Insights: open rate dropped 40% in last 3 sends IP reputation degrading Pause campaigns. Run Subscribers → Email verification on the list. Investigate recent content for unsubscribe spikes.
Test diagnostic lands in spam, headers show "spf=fail" SPF record doesn't include your sending IP / provider Update SPF record at your DNS host. Add the sending vendor's SPF include (e.g. include:amazonses.com).
Test diagnostic lands in spam, body has spam-trigger words Content filtering Re-review subject line + first paragraph. Avoid ALL CAPS, excessive punctuation, link-only content.
Test diagnostic doesn't arrive at all IP blocklisted Check the sending IP at mxtoolbox.com → blocklist lookup. Request delisting per the blocklist's process.

Pause and isolate the bad cohort

If only some recipients land in spam, segment the list:

  • Subscribers → Filter by domain → check open rates per ISP (Gmail / Outlook / Yahoo / corporate).
  • A 0% open rate on @gmail.com while @outlook.com is normal → your Gmail-side reputation is hurt. Investigate recent send patterns to Gmail addresses.
  • Pause sends to the problem segment until you've remediated content / reputation.
Advanced: SPF / DKIM / DMARC tuning for operators

The three authentication standards form the deliverability foundation. All three must pass for ISPs to trust the sender.

SPF (Sender Policy Framework — RFC 7208)

A DNS TXT record listing which IPs / domains are authorized to send for your domain. Lookup:

dig TXT yourdomain.com +short | grep spf
# Expected: "v=spf1 include:amazonses.com -all"

Common gotchas:

  • Multiple v=spf1 records on the same domain — SPF requires exactly ONE. Merge into one record.
  • ~all (soft fail) instead of -all (hard fail) — -all is preferred for production.
  • Sending IP not in the record. Use dig to verify; add the include statement.

DKIM (DomainKeys Identified Mail — RFC 6376)

Cryptographic signature on every outgoing message. The public key is published in DNS at <selector>._domainkey.yourdomain.com. AcelleMail generates the keypair via the sending-server's Verify domain wizard.

# Check the DKIM record exists
dig TXT default._domainkey.yourdomain.com +short
# Expected: "v=DKIM1; k=rsa; p=MIGfMA0..."

Common gotchas:

  • DNS record published but with line breaks — receivers can't parse. Re-publish as single-line.
  • Selector mismatch — AcelleMail uses <servername>._domainkey by default; if you customized the selector during install, verify the record name matches.

DMARC (Domain-based Message Authentication, Reporting & Conformance — RFC 7489)

Tells receivers what to do when SPF or DKIM fails:

dig TXT _dmarc.yourdomain.com +short
# Expected: "v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@yourdomain.com"

Migration path (always start permissive, ramp to strict):

  1. p=none; rua=mailto:reports@yourdomain.com — monitor; receivers send aggregate reports, no policy applied.
  2. After 2-4 weeks of clean reports → p=quarantine; pct=10 — 10% of failing mail goes to spam.
  3. Ramp pct to 100 over 2 weeks → switch to p=reject only after 100% pass rate.

Going straight to p=reject without ramping breaks ALL your mail if any auth is misconfigured.

Inspecting Authentication-Results of a received message:

# Send a test → grep the headers
grep -E "Authentication-Results|Received-SPF|DKIM-Signature" /path/to/saved-email

Look for dmarc=pass AND spf=pass AND dkim=pass. Any failure → fix that side specifically before retrying.

Engagement-driven reputation — ISPs increasingly weight subscriber engagement over pure auth. Even with green SPF/DKIM/DMARC, if your open rate is <10% over a 30-day window, Gmail / Outlook may demote you. Mitigation: aggressive list hygiene (unsubscribe inactive subscribers after 6 months), re-engagement campaigns to dormant cohorts before re-engaging them in regular sends.

Blocklist monitoring — periodic check at mxtoolbox.com for your sending IP + sending domain. Major lists: Spamhaus SBL/XBL/CSS, SpamCop, Barracuda. Each list has its own delisting form.

Related articles

18 comments

10 comments

  1. akira.tnk88
    What about the case where campaign:rerun itself crashes silently? We had cron running but :rerun was failing on a deleted customer and just bailing out. No alerts
    1. admin
      Good question. The campaign:rerun audit writes to laravel.log only when the audit decides to force-resume — pure noop runs are silent. We'll add an info-level heartbeat in a future Acelle release to make it easier to monitor
    2. admin (edited)
      Good catch. The bounds (200/32) are hardcoded in the runtime. We've discussed making them configurable; not a near-term priority but it's tracked.
  2. tnovak.cz
    this article saved me about 4 hours of debugging today. the diagnostic order at the top is exactly the workflow i needed.
    1. admin
      Thanks for the kind words. We try to keep these source-grounded so they age well.
    2. admin (edited)
      Glad it landed. Drop suggestions in the comments and we'll incorporate them on the next refresh.
  3. sofia.costa.pt
    Pro-tip: set `pm.max_children` on your PHP-FPM pool to at least 2x your supervisor worker count. Otherwise even ack-fast endpoints choke when the queue rate goes up.
  4. aditi.s.bom
    Confirming the campaign:rerun auto-fix actually works. We had a worker OOM mid-batch last week, walked away thinking we'd need to manually intervene, came back in 15 minutes and it had recovered itself.
  5. priya.iyer.ops
    what about the cae where campaign:rerun itself crashes silently? we had cron running but :rerun was failing on a deleted customer and just bailing out. no alerts.
    1. admin
      we tested this with up to 1m subscribers on a $40/mo vps. past that you start needing query optimization. below that, the defaults are fine. anyway
  6. d.cohen.tlv
    Sent this to my whole ops team. Should be required reading before anyone touches the prod queue.
  7. rafa.silva.br
    When you say to bump wait_timeout to 86400, does that need a MySQL restart or is it dynamic? We're on RDS so restarts are expensive.
  8. lucas.bernard.…
    Thanks for grounding this in actual source — much better than the generic Laravel advice you find on Stack Overflow.
  9. aisha.khan.pak
    Question: in step 4, the campaign log line about 'force resuming' — does that show up in laravel.log or only the per-campaign log file? Our laravel.log seems silent on this.
    1. admin (edited)
      Honest answer: it depends on your provider. SES handles it gracefully; Mailgun is stricter. We'll add a provider-by-provider table in the next revision.
    2. admin
      yes — strict alignment requires the from: domain to match exactly. subdomain-level (`bounce.example.com` vs `example.com`) passes relaxed but fails strict. most operators run relaxed; the rare strict-dmarc setups need explicit subdomain dkim configuration...
    3. admin (edited)
      We're aware of the silent-bail-out on deleted customers — there's an open issue for it. Workaround for now: monitor the campaign:rerun log for absence of expected log lines, alert when silent for > 20 min.
  10. ahmed.hassan.c…
    We hit cause #5 last quarter — SES sandbox limits we didn't know about. The 'wait it out' advice is right. We tried aggressive retries first and it just made things worse.

More in Troubleshooting