Profile    Mohammed Shiroz Status   Loading  
Logo
Share This
Back to blog
Filter by:
Tags
//Article title

Why Your Emails Land in Spam: SPF, DKIM and DMARC Explained

About Post

The password reset feature works perfectly. The code runs, the mail is sent, the log says success. The user just never sees it, because it's sitting in their spam folder between a lottery win they never entered and an invoice for something they never ordered.

Nothing in your app is broken. The problem is that the receiving mail server doesn't believe the email is really from you. And by the rules of email, it's right to be suspicious.

Three DNS records fix most of this: SPF, DKIM and DMARC. They sound like alphabet soup, but each one answers one simple question.

Why email needs proof at all

Email was designed in a friendlier era. The protocol that moves it, SMTP, lets the sender write any From address they like. Nothing in the basic protocol stops a server somewhere from sending mail "from" your domain.

Spammers and phishers noticed a long time ago. So modern receivers (Gmail, Outlook, Yahoo and the rest) check every incoming message for evidence that the domain in the From line actually authorised it. No evidence, lower trust. Low trust plus anything else slightly odd, and you're in spam or rejected outright.

That checking got stricter for everyone in 2024, when Google and Yahoo started requiring bulk senders to authenticate their mail with SPF, DKIM and DMARC. Even if you only send a handful of receipts a day, the same checks decide where your mail lands.

SPF: who is allowed to send

SPF (Sender Policy Framework) is a list, published in DNS, of the servers allowed to send mail for your domain. Think of it as a guest list at the door.

example.com.  TXT  "v=spf1 include:spf.your-provider.example ~all"

This says: servers listed by my email provider may send for me, and anything else should be treated with suspicion (~all is a "soft fail"; -all is a hard fail).

The gotchas that bite in production:

  • Only one SPF record per domain. Add a second one for your new marketing tool and both become invalid. Merge them into one record with two includes.
  • There's a limit of 10 DNS lookups. Every include can trigger more lookups. Stack enough services and SPF fails with a "too many lookups" error.
  • SPF checks the envelope sender (the hidden Return-Path), not the visible From. That detail is why SPF alone isn't enough, and why DMARC exists.
  • Forwarding breaks it. When a mail is forwarded, it arrives from the forwarder's server, which isn't on your list.

DKIM: a signature that travels with the mail

DKIM (DomainKeys Identified Mail) works like a wax seal. Your sending service signs certain headers and the body with a private key. You publish the matching public key in DNS, under a "selector":

s1._domainkey.example.com.  TXT  "v=DKIM1; k=rsa; p=MIIBIjANBgkq..."

The receiver reads the signature, fetches the public key and checks that the message wasn't changed on the way. Because the signature is part of the message, it usually survives forwarding, which SPF doesn't.

Most providers give you two or three CNAME records to add instead of a raw key, so they can rotate keys for you. The classic mistake is verifying the domain in the provider's dashboard and forgetting to add those records at all.

DMARC: tying it to the name people see

Here's the gap. SPF can pass for bounces.provider.example and DKIM can pass for provider.example, while the From line says [email protected]. Technically everything "passed", and a phisher could do the same.

DMARC closes that gap with alignment: at least one of SPF or DKIM must pass for the same domain that appears in the From line. It also lets you tell receivers what to do when that fails, and where to send reports.

_dmarc.example.com.  TXT  "v=DMARC1; p=none; rua=mailto:[email protected]"

The policy p has three levels: none (just report), quarantine (send failures to spam) and reject (refuse them). Start with none, read the reports for a while to find every legitimate service sending as you (the CRM, the helpdesk, the HR system nobody mentioned), fix them, then tighten.

The three side by side

Question it answersLives in DNS atWeak spot
SPFIs this server allowed to send for the domain?example.com TXTChecks the hidden sender; breaks on forwarding
DKIMWas this message signed by the domain and left unchanged?selector._domainkey.example.comSays nothing about the visible From on its own
DMARCDoes a pass match the From domain, and what if it doesn't?_dmarc.example.com TXTOnly as good as the SPF and DKIM setup under it

The Laravel side

Most deliverability problems I see in Laravel apps start with how mail leaves the server. Sending through PHP's mail() on a cheap VPS or shared host means your mail comes from an IP with no reputation, often no reverse DNS, and no DKIM. Use a transactional provider instead. Laravel supports several out of the box, including Amazon SES, Postmark, Resend and Mailgun.

MAIL_MAILER=ses
MAIL_FROM_ADDRESS="[email protected]"
MAIL_FROM_NAME="${APP_NAME}"

A few habits that help:

  • Send from a subdomain like mail.example.com for transactional mail, and a different one for newsletters. A marketing campaign with lots of complaints then can't drag down your password resets.
  • Make the From domain match the authenticated domain. Never send "from" a Gmail address through your own server. DMARC will fail by design.
  • Queue your mail with Mail::to($user)->queue(...) or a mailable that implements ShouldQueue, so a slow provider doesn't slow your request.
  • Handle bounces and complaints. Providers send webhooks for them. Keep sending to dead addresses and your reputation drops.

The Laravel mail docs cover the driver setup for each provider.

How to check in 30 seconds: send yourself a mail at a Gmail address, open it, choose "Show original", and look for SPF, DKIM and DMARC. You want three PASS results. Anything else tells you exactly which record to fix.

Authentication is the ticket, not the seat

Passing all three doesn't guarantee the inbox. It proves who you are. Where you land still depends on reputation: bounce rates, spam complaints, whether people open your mail, and whether your content looks like something people asked for.

But without authentication, reputation never gets a chance. Get the three records right first, then worry about the rest.

Which one caught you out first: the duplicate SPF record, the missing DKIM CNAMEs, or a DMARC report revealing a service you didn't know was sending as you?

Comments (0)
Leave your review

Thanks for your valuable comments. Your comments has been updated and appreciate your getting in touch...

01. About Shiroz

Mohammed Shiroz

Hi, I'm Mohammed Shiroz, a software engineer and AI enthusiast from Sri Lanka who turns ideas into intelligent, real-world solutions. With over 9 years of hands-on experience, I currently lead real estate ERP development at Kate Group, a...

03.My Projects

04. Categories

Ready To order Your Project ?

Get in Touch
Close