Security

How Email Actually Works: SMTP, DNS, SPF, DKIM, DMARC, MX, Bounces, and Deliverability

Learn how email works from send to inbox, including SMTP, DNS and MX records, SPF, DKIM, DMARC, ARC, bounces, queues, and deliverability.

Aarav Sharma

Aarav Sharma

September 2, 202636 min read
Share
How email actually works: the path from an application through SMTP, DNS and MX to inbox, spam or reject

Introduction

You call sendEmail(). The API returns success. Job done, right?

Not quite.

Between clicking Send and seeing a message in someone's inbox, several independent systems have to cooperate. SMTP transfers the message, DNS tells servers where to send it, SPF and DKIM help authenticate it, DMARC connects that authentication to the visible sender, and the receiving provider still has to decide whether your perfectly valid email deserves the inbox.

If those acronyms are already blurring together, don't worry. We'll expand every one of them and give each a plain-English analogy before we go deep.

Understanding how email works turns "the customer didn't receive the email" from a guessing game into something you can actually debug.

The easiest way to understand all of this is to follow one email from your application to the recipient.

TL;DR

Email delivery is a multi-step process. SMTP transfers the message, DNS and MX records locate the recipient's mail server, SPF and DKIM authenticate sending infrastructure and signatures, and DMARC checks whether those authenticated identities align with the domain the user sees in the From: header.

Passing all of them still doesn't guarantee the inbox. Receiving providers also consider reputation, complaints, sending patterns, message quality, and other signals when deciding whether to accept, reject, defer, or spam-folder a message.

The Acronym Decoder

Every acronym in this article, with its full name and a one-line analogy. Think of email delivery as a courier dropping a parcel at a large office building. That single picture carries most of the way through.

AcronymFull nameWhat it isAnalogy
SMTPSimple Mail Transfer ProtocolThe protocol that moves mail between systemsThe scripted handover conversation at the delivery counter
DNSDomain Name SystemThe internet's directory, mapping names to addresses and settingsThe address book you check before you drive anywhere
MXMail Exchanger (a DNS record type)Says which servers receive mail for a domainThe "deliveries round the back" sign pointing to the loading dock
MTAMail Transfer AgentA server that sends, routes, or receives mailThe courier van and the sorting depot
MUAMail User AgentThe email client a human usesThe person at the desk who actually opens the envelope
SPFSender Policy FrameworkLists which servers may send using your domain's SMTP identityThe approved-courier list at the security desk
DKIMDomainKeys Identified MailA cryptographic signature proving a domain signed the message and it wasn't alteredA tamper-evident wax seal that travels with the envelope
DMARCDomain-based Message Authentication, Reporting, and ConformanceChecks that authenticated identities match the visible sender, and publishes a policyThe receptionist comparing the name on the letterhead to the name on the courier's paperwork
ARCAuthenticated Received ChainPreserves authentication results across forwarding hopsA signed chain-of-custody log, stamped at every handoff
TLSTransport Layer SecurityEncryption for the connectionA sealed, opaque courier bag
PTRPointer record (reverse DNS)Maps an IP address back to a hostnameCaller ID for your mail server
DSNDelivery Status NotificationThe machine-readable bounce messageThe "return to sender" slip with a reason code
RFCRequest for CommentsThe published internet standards documentsThe rulebook everyone agreed to follow
MTA-STSMail Transfer Agent Strict Transport SecurityTells senders to require TLS to your domainA posted policy: "sealed bags only, refuse anything else"
BIMIBrand Indicators for Message IdentificationShows a verified brand logo next to your mailThe verified badge on the envelope

You Clicked Send. What Happens Next?

How an email travels from an application through SMTP and DNS to the recipient inbox

Figure — The end-to-end path from your application to the recipient's mailbox decision.

Suppose your application sends:

From: billing@example.com

To: alice@gmail.com

Subject: Your invoice is ready

SMTP itself is designed to transfer mail between systems, and DNS MX records are normally used to locate the servers responsible for receiving mail for a domain.

This gives us the first useful debugging rule:

Your application successfully handing an email to a provider does not mean the recipient received it.

Handing a parcel to a courier is not the same as the parcel arriving. There are still several systems between those two events.

First: An Email Has More Than One "Sender"

One of the strangest things about email is that a message can have several sender identities.

Consider:

From: billing@example.com

Return-Path: bounce@mail.example.com

DKIM-Signature:

d=example.com;

s=mail2026;

These fields aren't interchangeable.

The analogy: a physical letter has a return address printed on the outside of the envelope, a letterhead printed on the page inside, and a wax seal holding the flap shut. Three different places a name can appear, and nothing forces them to match.

The From address is the letterhead. It's what the recipient normally sees, and historically anyone could print anything on it.

The envelope sender, which eventually appears as the Return-Path, is the return address on the outside. It's part of SMTP delivery and is commonly used for bounce handling. Most recipients never look at it.

The DKIM signing domain, represented by d=, is the wax seal. It identifies the domain taking responsibility for the cryptographic signature.

Why does email need all of these identities?

Because email wasn't designed as one giant protocol. Delivery, message formatting, authentication, and policy evolved as separate layers.

Keep those identities in mind. They'll become important when we reach DMARC.

SMTP: The Conversation That Moves the Email

SMTP command and response flow between sending and receiving mail servers

Figure — SMTP is a structured command-and-response conversation between mail systems.

SMTP stands for Simple Mail Transfer Protocol.

The analogy: SMTP is the scripted exchange at a delivery counter. Who are you? Who is this from? Who is it for? Here's the parcel. Signed for, thank you. Every step gets a numeric acknowledgement so both sides know exactly where they are.

Despite everything we've added around email over the years, the basic SMTP conversation is surprisingly readable.

A simplified exchange looks like this:

Client: EHLO mail.example.com

Server: 250-mail.gmail.com at your service

Server: 250-STARTTLS

Server: 250 SIZE 35882577

Client: MAIL FROM:<bounce@example.com>

Server: 250 OK

Client: RCPT TO:<alice@gmail.com>

Server: 250 OK

Client: DATA

Server: 354 Start mail input

Client: From: billing@example.com

Client: To: alice@gmail.com

Client: Subject: Your invoice is ready

Client:

Client: Your invoice is attached.

Client: .

Server: 250 OK

The sender identifies itself, specifies the envelope sender, specifies the recipient, sends the message, and receives status responses.

EHLO is the modern greeting ("Extended HELLO"), replacing the original HELO. The server answers with a list of extensions it supports, which is how features like TLS, authentication, and size limits get negotiated.

RFC 5321 defines SMTP transport and relay behavior.

Submission Looks Slightly Different

The exchange above is a server-to-server transfer. When your application submits mail to a provider, two extra steps appear: encryption and authentication.

Client: EHLO app.example.com

Server: 250-smtp.provider.com

Server: 250-STARTTLS

Server: 250 AUTH PLAIN LOGIN

Client: STARTTLS

Server: 220 Ready to start TLS

... TLS handshake, conversation restarts encrypted ...

Client: AUTH PLAIN <base64 credentials>

Server: 235 Authentication successful

Client: MAIL FROM:<bounce@example.com>

... and onward as before

If you've ever wondered where your SMTP username and password actually go, that's the step.

Ports 25, 587, and 465

This distinction causes plenty of confusion.

Port 25 is primarily used for SMTP relay between mail servers. Most residential ISPs and cloud providers block outbound port 25 by default, which is why you can't usually send mail straight from an application server.

Port 587 is the standard message submission port, used when an application or mail client submits outgoing mail to a provider. The connection starts in the clear and upgrades to encryption via STARTTLS.

Port 465 is submission over implicit TLS, meaning the connection is encrypted from the very first byte, with no plaintext phase to upgrade from. RFC 8314 recommends implicit TLS in preference to connecting to the cleartext port and negotiating TLS with STARTTLS.

The IETF deliberately separates message submission from mail relay. RFC 6409 specifies message submission, normally over port 587, while SMTP relay continues on port 25. RFC 8314 later re-established port 465 for submission over implicit TLS.

In practice: use 587 or 465, whichever your provider recommends, and never send credentials over an unencrypted connection.

So when your Node.js application connects to an SMTP provider on port 587, it isn't normally connecting directly to Gmail's receiving server.

It's submitting mail to a server that will deliver it for you.

How Does SMTP Know Where gmail.com Is?

DNS MX lookup showing how a sending server finds the recipient mail server

Figure — DNS MX lookup identifies the mail servers responsible for a destination domain.

Suppose we're sending to:

alice@gmail.com

The sending mail server needs to answer:

Which server accepts email for gmail.com?

That's a DNS problem.

DNS stands for Domain Name System. It's the internet's directory service, turning human-readable names into machine-usable addresses and configuration.

More specifically, it's an MX record problem.

MX stands for Mail Exchanger.

The analogy: a company's street address gets you to the front of the building. The MX record is the sign that says deliveries round the back. It tells couriers which door actually accepts parcels, which is often not the door customers walk through.

SMTP uses DNS MX records to identify mail exchangers for the destination domain.

MX records can also have priorities:

10 mx1.example.com

20 mx2.example.com

Lower preference values are preferred. If the preferred server can't be reached, another MX can provide a fallback, like a second loading dock that opens when the first one is full.

When There Is No MX Record

Two cases are worth knowing, because both show up in real debugging.

Implicit MX. If a domain has no MX record at all, RFC 5321 says the sender falls back to the domain's A or AAAA record and tries to deliver there. This is why mail sometimes lands on a web server that was never meant to receive it.

Null MX. RFC 7505 defines a way for a domain to say "we accept no mail, ever": a single MX record with preference 0 and a target of . (a lone dot).

example.com. IN MX 0 .

It must be the only MX record for the domain. Senders should reject immediately rather than falling back to the A record. If you own domains that never receive mail, publishing a null MX plus a restrictive SPF and DMARC record is good hygiene.

Your Website and Email Don't Have to Live Together

Suppose:

example.com

has these DNS records:

A → 203.0.113.10

MX → mail.provider.com

TXT → SPF / verification records

The A record might point to your web server.

The MX record points to infrastructure that receives email.

TXT records are commonly used for email authentication configuration such as SPF, DKIM public keys, and DMARC policies.

This is why changing web hosting doesn't necessarily affect email, unless someone accidentally replaces the DNS zone while doing it.

It's an easy mistake to make when DNS is being changed.

The Email Reaches Gmail. Why Should Gmail Trust You?

SMTP solved:

How do I transfer this message?

MX solved:

Where should I transfer it?

Neither answered:

Is this sender legitimate?

Historically, email made sender impersonation surprisingly easy. Anyone could print your letterhead. SPF, DKIM, and DMARC were introduced to address different parts of that problem.

They overlap, but they are not three versions of the same thing.

SPF: Is This Server Allowed to Send for This Domain?

SPF authentication checking whether a sending server is authorized for a domain

Figure — SPF evaluates whether the connecting infrastructure is authorized by the SMTP identity's policy.

SPF stands for Sender Policy Framework.

The analogy: SPF is the approved-courier list taped to the security desk. "We only accept parcels from these three delivery companies." The guard checks the van in the driveway, not the letter inside it.

Think of SPF as a domain publishing a list of infrastructure authorized to send mail using its SMTP identity.

A simplified SPF record might look like:

example.com TXT

"v=spf1 ip4:203.0.113.10 include:_spf.provider.com -all"

SPF uses DNS TXT records to authorize hosts for SMTP identities such as MAIL FROM and HELO.

Reading an SPF Record

Each term is a mechanism, and each mechanism can carry a qualifier that says what to do on a match:

QualifierResultMeaning
+ (default)passAuthorized
-failNot authorized, reject
~softfailNot authorized, but accept and mark
?neutralNo statement either way

So the -all at the end of the example means "anything not listed above fails." Using ~all instead is the softer version, and it's a reasonable starting point while you're still discovering which systems send on your behalf. Once you're confident the list is complete, tighten to -all.

Three SPF Rules That Break Real Systems

One record only. A domain must publish exactly one SPF record. Two or more produce a permerror, and the entire check fails. When you add a new email vendor, merge their include: into your existing record. Never publish a second one.

The 10-lookup limit. RFC 7208 caps the number of DNS-querying terms at 10 per evaluation. include, a, mx, ptr, exists, and redirect all count. ip4, ip6, and all do not. Exceed it and you get a permerror, which DMARC treats as a failure. This is one of the most common silent breakages in production: you add a fourth vendor, quietly cross the limit, and authentication stops working for everything.

There's also a separate limit of two void lookups, meaning queries that return nothing.

Don't use ptr. RFC 7208 lists the ptr mechanism as "do not use." It's slow, unreliable, and some receivers ignore it. If a vendor's setup guide still recommends it, that guide is out of date.

If you're near the lookup limit, options include removing vendors you no longer use, using ip4/ip6 for infrastructure you control, or SPF flattening. Flattening trades lookup relief for staleness risk: you're hardcoding IPs that your provider may rotate without telling you. Automate it or don't do it.

The SPF Detail That Matters

SPF doesn't simply authenticate whatever address the user sees beside From: in Gmail.

It operates on SMTP identities, the return address on the outside of the envelope.

This distinction is one reason SPF alone isn't enough to stop visible sender spoofing. The guard verified the van. Nobody checked the letterhead.

And it becomes even more interesting when forwarding enters the picture.

DKIM: Was This Message Really Signed by That Domain?

DKIM email authentication using a DNS-published public key to verify a message signature

Figure — DKIM uses a DNS-published public key to verify a signature carried by the message.

DKIM stands for DomainKeys Identified Mail.

The analogy: DKIM is a tamper-evident wax seal. It proves two things at once: that the claimed domain really applied the seal, and that nobody opened the envelope in transit. Crucially, the seal travels with the letter, so it still works after the letter is passed between offices.

Instead of checking the connecting server's IP address, DKIM uses cryptography.

The corresponding public key is published in DNS.

DKIM allows a signing domain to associate itself with a message using a cryptographic signature, with the public key retrieved from the signing domain.

Selectors

The s= value is called the selector.

The analogy: it's which key on the keyring. Selectors let a domain maintain multiple DKIM keys at once, which is useful for key rotation or for different email providers.

For example:

google._domainkey.example.com

sendgrid._domainkey.example.com

marketing._domainkey.example.com

Each can point to a different public key.

Key Length and a DNS Trap

RFC 8301 updated DKIM to forbid rsa-sha1 and to require that verifiers reject RSA keys shorter than 1024 bits. RFC 8463 later added ed25519-sha256 as an alternative algorithm.

In practice, 2048-bit RSA is the current default recommendation. 1024-bit is the protocol floor, not a target.

The trap: a 2048-bit public key is longer than the 255-character limit for a single DNS string. It must be split into multiple quoted strings inside one TXT record, which the DNS resolver then concatenates.

mail2026._domainkey IN TXT ( "v=DKIM1; k=rsa; p=MIIBIjANBgkq..."

"...rest of the key here" )

Some DNS control panels do this for you. Some silently truncate. If DKIM works with a 1024-bit key and breaks with a 2048-bit one, this is almost always why.

SPF vs DKIM: Why Do We Need Both?

Because they prove different things.

SPFDKIM
Authorizes sending hostsVerifies a cryptographic signature
Primarily evaluates SMTP identitiesAssociates a signing domain with the message
Depends on the connecting infrastructureSignature travels with the email
Can be disrupted by forwardingCan survive ordinary forwarding if signed content isn't modified
Checks the vanChecks the seal

SPF asks:

Was this machine authorized to use this SMTP domain?

DKIM asks:

Can this message's signature be verified against this signing domain?

Neither, by itself, guarantees that the domain visible to the user in From: is the identity that passed authentication.

That's the gap DMARC addresses.

DMARC: Do the Authenticated Domains Match the Sender the User Sees?

DMARC checking SPF and DKIM authentication alignment with the visible From domain

Figure — DMARC connects SPF/DKIM authentication results to the visible From domain through alignment.

DMARC stands for Domain-based Message Authentication, Reporting, and Conformance.

The analogy: DMARC is the receptionist who finally compares the letterhead to the paperwork. The guard checked the van. The seal was intact. But whose name is actually on the letter, and does it match? And if it doesn't, what has the company posted that we should do about it?

This is where the distinction matters.

Imagine:

From: ceo@yourcompany.com

SPF authenticated:

random-attacker.com

DKIM signed by:

random-attacker.com

SPF might pass.

DKIM might pass.

But neither authenticated domain matches:

yourcompany.com

The attacker used their own van and their own seal, then printed your letterhead. Both checks passed, and the message is still a forgery.

DMARC introduces alignment.

For DMARC to pass, an authenticated SPF or DKIM domain needs to align appropriately with the domain in the visible From: address. Only one of the two needs to align.

Relaxed vs Strict Alignment

Alignment has two modes, set by the aspf and adkim tags:

  • Relaxed (the default): the organizational domains must match. mail.example.com aligns with example.com.
  • Strict: the domains must match exactly. mail.example.com does not align with example.com.

Relaxed is the right default for almost everyone. Strict is for organizations that have fully inventoried their sending and want no subdomain flexibility.

DMARC Policies: None, Quarantine, Reject

A simplified DMARC record looks like:

_dmarc.example.com TXT

"v=DMARC1; p=none; rua=mailto:dmarc@example.com"

Useful tags:

TagPurpose
pPolicy for the domain: none, quarantine, or reject
spPolicy for subdomains, if different from p
ruaWhere to send aggregate reports (daily XML summaries)
rufWhere to send failure reports (per-message, sparsely supported)
aspf / adkimAlignment mode, r for relaxed or s for strict
tTest mode, for staged rollout

The familiar policies are:

p=none

p=quarantine

p=reject

p=none

Monitor authentication without asking receivers to quarantine or reject based on the DMARC policy.

Useful when initially deploying DMARC and collecting reports. This is where everyone starts, and where too many people stop.

p=quarantine

Ask receivers to treat failing mail suspiciously, commonly resulting in spam-folder treatment.

p=reject

Ask receivers to reject mail that fails the DMARC policy.

A sensible rollout starts with monitoring, fixes legitimate senders that aren't aligned correctly, and only then moves toward stronger enforcement.

What Changed in 2026: RFC 9989

This is worth knowing because a lot of published guidance is now out of date.

DMARC was originally described in RFC 7489, an Informational document from 2015. In May 2026 the IETF published RFC 9989, which obsoletes RFC 7489 and RFC 9091 and puts DMARC on the Standards Track as a Proposed Standard for the first time. Two companion documents were published alongside it: RFC 9990 for aggregate reporting and RFC 9991 for failure reporting.

What actually changes for you:

Your existing records still work. The version tag is still v=DMARC1, and receivers must ignore tags they don't recognize. Nothing breaks. Despite what some vendor blogs claim, there is no "DMARC2."

Three tags are now historic: pct (percentage rollout), rf (report format), and ri (report interval). Remove them on your next DNS update.

`pct` has a replacement. Staged rollout is now handled by the new t tag. t=y downgrades the effective policy by one step, so p=reject; t=y is treated as quarantine. This is the one genuinely new tag in RFC 9989.

The Public Suffix List is replaced by a DNS "tree walk." Instead of consulting a static list to find your organizational domain, a receiver queries progressively higher labels, up to eight lookups, until it finds a DMARC record.

`np` is not new. It sets policy for non-existent subdomains and originated in the experimental RFC 9091 back in 2021. RFC 9989 formalizes it.

One practical caveat: as of mid-2026, the major receivers reliably honor p, sp, and alignment, but none has publicly documented support for np or the tree walk. The standard has landed; deployment is still catching up. Write your records for what receivers actually do today, and drop the historic tags as housekeeping.

Why Forwarding Makes SPF Complicated

Consider this:

Your Mail Server

company.com

│ forwards email

Gmail

Your domain's SPF record authorized your original sending server.

But Gmail may now see the forwarding server making the SMTP connection.

That server might not be authorized by your SPF record.

The analogy: your approved-courier list named DHL. DHL delivered to the first office, which then had a completely different courier carry the parcel onward. The final building checks its list, sees an unapproved van, and refuses it. Nothing about the letter changed. Only the vehicle did.

So SPF can fail even though the original message was legitimate. SPF's own specification discusses complications introduced by mediators such as forwarding systems.

DKIM often behaves better here because the cryptographic signature travels with the message, provided the forwarding system doesn't modify signed portions in a way that invalidates it. The seal survives the vehicle change.

That is why SPF should not be treated as the whole authentication story.

ARC: The Fix for the Forwarding Problem

ARC preserving email authentication results when a message is forwarded

Figure — ARC preserves authentication context when forwarding changes the connecting server.

ARC stands for Authenticated Received Chain, defined in RFC 8617.

The analogy: a chain-of-custody log. Each intermediary that handles the message records what the authentication looked like when it arrived at their door, then signs that record. A downstream receiver can read the chain and conclude: "SPF fails for me now, but this trusted forwarder attests that it passed before they touched it."

Each ARC-participating hop adds three headers:

ARC-Authentication-Results

ARC-Message-Signature

ARC-Seal

Together they form a sealed, ordered chain that a final receiver can validate.

Two practical notes:

It's Experimental, but widely deployed. RFC 8617 is formally an Experimental specification, not Standards Track. That hasn't stopped adoption. Google deployed ARC across its email services, and Microsoft lets Exchange Online and Defender administrators configure Trusted ARC Sealers, so ARC results from intermediaries they trust can prevent legitimate forwarded mail from failing authentication.

You mostly don't implement it, you benefit from it. If you run a mailing list, a forwarding service, or a security gateway, you should seal. If you're an application sending transactional mail, ARC is something that happens downstream. It's worth knowing it exists so that when a customer says "it worked until our IT team put a gateway in front of it," you know what to ask about. Not every gateway seals, and an unsealed hop breaks the chain.

The Email Passed SPF, DKIM, and DMARC. Inbox?

Email deliverability decision based on authentication, reputation, spam signals, and engagement

Figure — Inbox placement depends on authentication plus reputation, complaints, traffic, content, and engagement.

Not necessarily.

This is the difference between delivery and deliverability.

A receiving server might accept your email:

250 OK

but that does not mean:

PRIMARY INBOX 🎉

The analogy: the guard let you through the door. That doesn't mean the parcel reached the executive's desk. It might be sitting in the mailroom, in the pile nobody sorts.

After accepting the message, the provider can still classify it.

Authentication establishes useful identity and trust signals.

Deliverability is the broader question of whether your mail actually reaches the place where users are likely to see it.

Gmail considers authentication alongside factors such as spam complaints, sending practices, infrastructure configuration, reputation, and sending volume. Google explicitly does not guarantee inbox placement merely because a sender uses an email provider or passes basic authentication.

Why Legitimate Email Still Goes to Spam

Imagine two domains.

Domain A

Sends consistently

Recipients expect the email

Very few complaints

SPF configured

DKIM configured

DMARC configured

Valid DNS

Domain B

Brand-new sending domain

0 emails yesterday

100,000 emails today

High complaint rate

Old purchased mailing list

Both might technically authenticate their messages.

A mailbox provider would still have good reasons to treat them differently. Domain B is a courier company that appeared this morning and immediately tried to deliver a hundred thousand parcels. Valid paperwork doesn't make that look normal.

Google recommends gradually increasing sending volume, monitoring reputation, avoiding sudden volume spikes, sending only to recipients who want the messages, and keeping user-reported spam rates low.

For Gmail specifically, the current guidance says senders should keep spam rates below 0.1% and avoid ever reaching 0.3% or higher. Since June 2024, senders at or above 0.3% are ineligible for delivery mitigation until they stay below that threshold for seven consecutive days.

Authentication helps establish who is sending the message. It does not, by itself, establish that recipients want to receive it.

What Is an Email Bounce?

Email bounce flow showing temporary 4xx failures and permanent 5xx failures

Now suppose the email can't be delivered.

SMTP gives us response codes that tell us what happened.

A simplified example:

MAIL FROM:<bounce@example.com>

250 OK

RCPT TO:<does-not-exist@example.net>

550 5.1.1 User unknown

That 550 tells us the receiving system is refusing the recipient.

Two numbering systems are in play here, and it helps to know which is which:

  • The three-digit reply codes (250, 421, 550) come from RFC 5321, the SMTP specification.
  • The dotted enhanced status codes (5.1.1) come from RFC 3463, and carry more specific diagnostic detail.
  • The structured bounce message that gets mailed back to you is a DSN, formatted per RFC 3464.

Enhanced status codes take this general form:

class.subject.detail

For example:

5.1.1

RFC 3463 defines classes beginning with 2, 4, and 5 for success, persistent transient failure, and permanent failure categories respectively.

In practical email systems, you'll often hear failures grouped into soft bounces and hard bounces.

Hard Bounce vs Soft Bounce

Figure — Temporary failures are retried with backoff; permanent failures should feed suppression.

Hard bounce

Usually indicates a permanent delivery problem. The "no such person at this address" sticker.

Examples include:

Mailbox doesn't exist

Invalid recipient

Domain doesn't exist

Permanent policy rejection

If:

alicee@example.com

doesn't exist, retrying it 50 times isn't persistence.

It's bad sender behavior.

The address should normally be suppressed or corrected.

Soft bounce

Represents a condition that may be temporary. The "office closed, try tomorrow" note.

Examples include:

Temporary server failure

Rate limiting

Mailbox temporarily unavailable

Receiving server overloaded

These are often candidates for retry.

But not:

retry();

retry();

retry();

retry();

retry();

immediately.

Retries need backoff.

Bounce Handling Is Part of Your Application

A production email system shouldn't simply have:

users

----------------

id

email

You often need a delivery state as well.

For example:

email_recipients

---------------------------

email

status

last_bounce_at

bounce_type

bounce_code

bounce_reason

suppressed_at

Then:

Permanent failure

Mark address invalid

Add to suppression list

Do not send again

Whereas:

Temporary failure

Retry later

Exponential backoff

This matters beyond simple efficiency.

Continuing to send repeatedly to invalid or uninterested recipients can hurt your reputation and therefore hurt delivery for your valid recipients too.

What Happens When You Send 100,000 Emails?

At small scale, email looks like:

sendEmail()

At production scale, it looks more like:

Application

Email Queue

Sending Workers

Email Provider / MTA

Recipient MX Servers

├── Gmail

├── Outlook

├── Yahoo

└── Private mail servers

SMTP Responses

Bounce / Event Processing

Suppression + Analytics

Why a queue?

Sending 100,000 messages synchronously from one API request is simply the wrong architecture.

The queue lets you control throughput, retries, concurrency, provider rate limits, and failure handling.

And different receiving providers may react differently to sudden traffic.

A production mail system therefore needs backpressure: when a receiving provider starts deferring mail, your system should slow down rather than hammering it harder. A loading dock that's waving you off is not a dock you should send more trucks to.

Mailbox Provider Requirements in 2026

Email authentication isn't merely an academic best practice anymore. All three major consumer providers now enforce baseline requirements, and non-compliant mail gets junked or rejected.

Google / Gmail

For mail sent to personal Gmail accounts, Google requires all senders to use SPF or DKIM, publish valid forward and reverse DNS (PTR) records, use TLS on connections, follow RFC 5322 message formatting, and maintain acceptable spam rates.

Senders sending close to 5,000 or more messages per day to personal Gmail accounts are classified as bulk senders and have additional requirements: both SPF and DKIM, a DMARC record, alignment, and one-click unsubscribe for marketing and subscribed messages. The classification is counted per primary domain and is permanent once triggered.

Google states that starting November 2025, Gmail began ramping up enforcement against non-compliant traffic, with messages subject to temporary and permanent rejections.

Microsoft / Outlook.com

Microsoft announced in April 2025 and began enforcing on 5 May 2025 its own requirements for high-volume senders, roughly 5,000+ messages per day to Outlook.com, Hotmail, and Live addresses: SPF, DKIM, and DMARC with at least p=none, aligned to SPF or DKIM.

Non-compliant mail is routed to Junk first, with rejection carrying this response:

550 5.7.515 Access denied, sending domain [SendingDomain]

does not meet the required authentication level

If you've only ever configured for Gmail, that error message is what a Microsoft-specific gap looks like.

Yahoo

Yahoo's requirements mirror Google's and have been enforced since February 2024: SPF and DKIM, DMARC at minimum p=none, alignment, spam rates under 0.3%, and one-click unsubscribe. Yahoo runs Sender Hub as its postmaster equivalent.

One-Click Unsubscribe

Both Google and Yahoo require RFC 8058 one-click unsubscribe for bulk marketing and subscription mail. Transactional messages such as receipts and password resets are exempt.

Two headers are required:

List-Unsubscribe: <https://example.com/unsub?id=abc123>, <mailto:unsub@example.com>

List-Unsubscribe-Post: List-Unsubscribe=One-Click

The rules that trip people up:

  • The List-Unsubscribe header must contain an HTTPS URI. A mailto: alone doesn't satisfy one-click.
  • The List-Unsubscribe-Post value must be exactly List-Unsubscribe=One-Click.
  • Both headers must be covered by your DKIM signature.
  • The endpoint must accept an HTTP POST with no login and return a 2xx status.
  • Requests must be honored within two days.

Microsoft recommends functional unsubscribe but hasn't formally mandated RFC 8058.

That means this isn't just:

"Configure SPF someday because it's nice to have."

For serious email infrastructure, authentication and sender hygiene are part of production readiness.

Transport Security Extras: MTA-STS, TLS-RPT, DANE, and BIMI

These sit one layer beyond the core stack. You don't need them on day one, but you should know what they are.

MTA-STS (Mail Transfer Agent Strict Transport Security, RFC 8461) lets your domain publish a policy saying "senders must use TLS with a valid certificate when delivering to us." Without it, an attacker can strip STARTTLS and downgrade the connection to plaintext. It's the "sealed bags only" sign.

TLS-RPT (SMTP TLS Reporting, RFC 8460) gives you daily reports on TLS failures other systems hit when delivering to you. It pairs naturally with MTA-STS.

DANE for SMTP (RFC 7672) achieves a similar goal using DNSSEC-signed TLSA records instead of an HTTPS-hosted policy file. It's more common in European and government infrastructure. MTA-STS is more common where DNSSEC isn't deployed.

BIMI (Brand Indicators for Message Identification) displays your verified brand logo beside your messages. It is not yet an RFC; it remains an IETF draft and industry specification. Prerequisites at Gmail are DMARC at enforcement (p=quarantine or p=reject) plus a certificate: either a VMC, which requires a registered trademark and also produces the blue verified checkmark, or a CMC, which Google began accepting in September 2024 and which shows the logo but not the checkmark. Microsoft Outlook does not support BIMI.

How to Debug "The Email Never Arrived"

This is the workflow we'd actually use.

Step 1: Did your application create the email?

Check your application logs.

password_reset_email_created

recipient=alice@example.com

message_id=msg_123

If not, you don't have an email problem yet.

You have an application problem.

Step 2: Did your email provider accept it?

Check the provider response.

accepted

queued

rejected

If your provider rejected it before sending, DNS at the recipient isn't your first problem.

Step 3: What did the recipient's mail server say?

Look for SMTP responses.

250 → accepted

4xx → temporary failure / defer

5xx → permanent failure or rejection

Enhanced status codes provide more specific diagnostic information.

Step 4: Did SPF pass?

Inspect the received message headers or your provider's delivery diagnostics. The Authentication-Results header is where receivers record their verdicts.

You'll often find something like:

spf=pass

or:

spf=fail

A spf=permerror is different and specific: it usually means more than one SPF record, or the 10-lookup limit was exceeded.

Step 5: Did DKIM pass?

Look for:

dkim=pass

If it fails, investigate the signature, selector, DNS public key, or message modification.

Step 6: Did DMARC pass?

Look for:

dmarc=pass

If SPF and DKIM appear healthy but DMARC fails, alignment is a strong suspect.

Step 7: Is a forwarder involved?

If the recipient forwards their mail, or their organization runs a security gateway, check for arc=pass in the headers. A broken or absent ARC chain explains a lot of "it only fails for this one customer" reports.

Step 8: Was the message accepted but filtered?

Now you're debugging deliverability rather than transport.

Check:

  • Spam folder
  • Sender reputation
  • Complaint rates
  • Sending volume
  • Domain/IP reputation
  • Content
  • Recipient engagement
  • Authentication consistency

For Gmail traffic, Postmaster Tools exposes dashboards for authentication, reputation, spam rate, and sender-requirement compliance. Yahoo's Sender Hub and Microsoft's SNDS offer rough equivalents.

Common Email Problems

SPF Passes but DMARC Fails

SPF can authenticate the envelope domain while your visible From: address uses another domain.

From:

billing@example.com

Envelope sender:

bounce@email-provider.net

SPF:

PASS

DMARC:

FAIL

Why?

The identities don't align. The return address on the envelope belongs to your provider; the letterhead is yours.

Fix the provider's custom return-path/bounce-domain configuration or ensure aligned DKIM authentication.

SPF Suddenly Breaks After Adding a Vendor

You added a fourth include: and everything stopped authenticating.

Check for permerror. You've either crossed the 10-lookup limit or published a second SPF record. Both fail the entire check, not just the new vendor.

DKIM Fails After Forwarding

A forwarding service or mailing list may modify the message after it was signed. Mailing lists that append footers or rewrite subject lines are the classic culprit.

If signed content changes, DKIM verification can fail because the cryptographic hashes no longer match. DKIM is specifically designed to verify that hashed signed content hasn't changed since signing.

ARC exists to give receivers a way to recover from exactly this.

SPF Fails After Forwarding

The final receiver sees the forwarding server's IP rather than the original sender.

That IP may not appear in the original domain's SPF policy.

This is a known limitation of relying on SPF through intermediaries, and another reason aligned DKIM matters more than aligned SPF.

Everything Passes but Email Goes to Spam

Authentication is not an inbox ticket.

Investigate:

  • complaint rate;
  • domain/IP reputation;
  • sudden volume changes;
  • recipient quality;
  • message type;
  • unsubscribe practices;
  • sending consistency.

For Gmail, user-reported spam rates above 0.1% already negatively affect inbox delivery for bulk senders, while 0.3% is an important upper threshold in its sender requirements.

You're Still Sending to Hard-Bounced Addresses

Do not keep sending to those addresses. Maintain a suppression list and don't continuously send to addresses known to be permanently invalid.

This wastes resources and damages sender hygiene.

Email Deliverability Best Practices

  • Configure SPF, DKIM, and DMARC. Even where only part of that stack is strictly required, deploying all three correctly gives receiving systems better authentication signals and protects your domain from spoofing.
  • Publish exactly one SPF record and stay under 10 lookups. Audit it whenever you add or remove an email vendor. Don't use the ptr mechanism.
  • Use 2048-bit DKIM keys and verify the DNS record actually resolves. Check for string-splitting problems after publishing, not after the first complaint.
  • Start DMARC carefully. Monitor with p=none first, read the aggregate reports, identify legitimate sending systems, fix alignment, then move toward enforcement. Use t=y for staged rollout rather than the retired pct tag.
  • Prefer aligned DKIM over aligned SPF. It survives forwarding. SPF often doesn't.
  • Warm up sending volume gradually. Don't take a domain from a few hundred messages to hundreds of thousands overnight. Google explicitly recommends gradual volume increases.
  • Separate transactional and marketing traffic where appropriate. Password resets and newsletters have very different recipient expectations and risk profiles. Subdomain separation protects your transactional reputation from your marketing reputation.
  • Process bounces automatically. Permanent failures should feed suppression logic; temporary failures need controlled retries with backoff.
  • Implement RFC 8058 one-click unsubscribe correctly, including the DKIM coverage and the POST endpoint, not just the header.
  • Monitor reputation, not just API success rates. Your email API returning 200 tells you almost nothing about long-term deliverability.

The Mental Model to Remember

If the acronyms start blending together, remember this:

SMTP

"Move the email."

The handover conversation at the counter.

DNS / MX

"Where should I send it?"

The sign pointing to the loading dock.

SPF

"Was this sending infrastructure authorized?"

The approved-courier list at the security desk.

DKIM

"Can I verify this domain's signature?"

The tamper-evident seal on the envelope.

DMARC

"Does the authenticated identity align with the sender users see, and what policy has the domain published?"

The receptionist comparing letterhead to paperwork.

ARC

"Did it authenticate before the forwarder touched it?"

The signed chain-of-custody log.

Bounce handling

"Why couldn't we deliver it?"

The return-to-sender slip.

Deliverability

"Even if it was accepted, where did it land?"

Front desk versus the executive's desk.

And the complete journey:

Application

SMTP Submission (587 / 465)

Sending MTA

│ DNS MX lookup

Recipient MTA

├── SPF

├── DKIM

├── DMARC

├── ARC (if forwarded)

├── DNS / PTR

├── Reputation

├── Spam signals

└── Provider policy

┌─────┼───────────┐

▼ ▼ ▼

Inbox Spam Reject

Bounce

Suppression / Retry

FAQ

What is SMTP in email?

SMTP stands for Simple Mail Transfer Protocol. It's the protocol used to submit and transfer email between mail systems. SMTP relay normally uses port 25, while authenticated message submission commonly uses port 587 with STARTTLS or port 465 with implicit TLS.

What is an MX record?

MX stands for Mail Exchanger. An MX record is a DNS record that identifies the mail server responsible for receiving email for a domain. Sending mail servers query MX records to determine where mail for a destination domain should be delivered. Lower preference numbers are tried first.

What is the difference between SPF, DKIM, and DMARC?

SPF (Sender Policy Framework) authorizes sending infrastructure for SMTP identities. DKIM (DomainKeys Identified Mail) attaches a cryptographic domain signature to the message. DMARC (Domain-based Message Authentication, Reporting, and Conformance) evaluates authentication in relation to the domain in the visible From: address and lets domain owners publish handling and reporting policies.

What is ARC in email?

ARC stands for Authenticated Received Chain (RFC 8617). It lets forwarding services and mailing lists record and cryptographically sign the authentication results they saw, so a downstream receiver can trust that a message authenticated correctly before it was forwarded, even if SPF now fails.

Does passing SPF, DKIM, and DMARC guarantee inbox delivery?

No. Authentication is an important deliverability signal, but mailbox providers also consider reputation, complaints, sending practices, traffic patterns, and other anti-abuse signals.

What is the difference between a soft bounce and a hard bounce?

A soft bounce generally describes a temporary delivery problem that may succeed later, while a hard bounce describes a permanent failure such as an invalid recipient. SMTP enhanced status codes distinguish temporary (4.x.x) from permanent (5.x.x) failure classes.

Why can SPF fail when an email is forwarded?

SPF evaluates the server connecting to the receiver. After forwarding, that may be the forwarding server rather than the server originally authorized by the sender's SPF policy.

What is the SPF 10-lookup limit?

RFC 7208 limits an SPF evaluation to 10 DNS-querying mechanisms. include, a, mx, ptr, exists, and redirect count toward it; ip4, ip6, and all do not. Exceeding the limit produces a permerror, which fails the whole check.

Is DMARC still RFC 7489?

No. RFC 9989, published in May 2026, obsoletes RFC 7489 and moves DMARC onto the Standards Track. Existing v=DMARC1 records still work, but the pct, rf, and ri tags are now historic, and staged rollout is handled by the new t tag.

Conclusion

Sending an email is easy. Delivering email reliably is a distributed-systems problem.

SMTP moves the message, DNS and MX records find the destination, SPF and DKIM provide authentication signals, DMARC connects those signals to the sender identity users actually see, and ARC keeps that chain intact through forwarding. After all that, mailbox providers still evaluate reputation and spam signals before deciding where the message belongs.

The practical takeaway is simple: don't stop monitoring at sendEmail().

Track SMTP responses, authenticate every sending domain, process bounces, suppress permanently invalid recipients, monitor reputation, and understand the difference between accepted, delivered, and inboxed.

Once that pipeline is clear, email becomes much easier to troubleshoot.

Need Help Building Reliable Email Infrastructure?

If your application depends on transactional email, notifications, bulk sending, or customer communication, reliable delivery requires more than integrating an email API.

Our development team can help design email pipelines, background workers, bounce processing, authentication, monitoring, and scalable backend systems that behave predictably in production.

Authoritative External References

Core protocol

  • RFC 5321 — Simple Mail Transfer Protocol — https://www.rfc-editor.org/rfc/rfc5321
  • RFC 6409 — Message Submission for Mail — https://www.rfc-editor.org/rfc/rfc6409
  • RFC 8314 — Cleartext Considered Obsolete: Use of TLS for Email Submission and Access — https://www.rfc-editor.org/rfc/rfc8314
  • RFC 7505 — A "Null MX" Resource Record for Domains That Accept No Mail — https://www.rfc-editor.org/rfc/rfc7505

Authentication

  • RFC 7208 — Sender Policy Framework (SPF) — https://www.rfc-editor.org/rfc/rfc7208
  • RFC 6376 — DomainKeys Identified Mail (DKIM) — https://www.rfc-editor.org/rfc/rfc6376
  • RFC 8301 — Cryptographic Algorithm and Key Usage Update to DKIM — https://www.rfc-editor.org/rfc/rfc8301
  • RFC 8463 — A New Cryptographic Signature Method for DKIM (Ed25519) — https://www.rfc-editor.org/rfc/rfc8463
  • RFC 9989 — Domain-Based Message Authentication, Reporting, and Conformance (DMARC) — https://www.rfc-editor.org/rfc/rfc9989
  • RFC 9990 — DMARC Aggregate Reporting — https://www.rfc-editor.org/rfc/rfc9990
  • RFC 9991 — DMARC Failure Reporting — https://www.rfc-editor.org/rfc/rfc9991
  • RFC 8617 — The Authenticated Received Chain (ARC) Protocol — https://www.rfc-editor.org/rfc/rfc8617

Bounces and status codes

  • RFC 3461 — SMTP Service Extension for Delivery Status Notifications — https://www.rfc-editor.org/rfc/rfc3461
  • RFC 3463 — Enhanced Mail System Status Codes — https://www.rfc-editor.org/rfc/rfc3463
  • RFC 3464 — An Extensible Message Format for Delivery Status Notifications — https://www.rfc-editor.org/rfc/rfc3464

Transport security and list management

  • RFC 8058 — Signaling One-Click Functionality for List Email Headers — https://www.rfc-editor.org/rfc/rfc8058
  • RFC 8460 — SMTP TLS Reporting — https://www.rfc-editor.org/rfc/rfc8460
  • RFC 8461 — SMTP MTA Strict Transport Security (MTA-STS) — https://www.rfc-editor.org/rfc/rfc8461
  • RFC 7672 — SMTP Security via Opportunistic DANE TLS — https://www.rfc-editor.org/rfc/rfc7672

Provider requirements

  • Google — Email Sender Guidelines — https://support.google.com/mail/answer/81126
  • Google — Email Sender Guidelines FAQ — https://support.google.com/mail/answer/14229414
  • Microsoft — Outlook's New Requirements for High-Volume Senders — https://techcommunity.microsoft.com/blog/microsoftdefenderforoffice365blog/strengthening-email-ecosystem-outlook%E2%80%99s-new-requirements-for-high%E2%80%90volume-senders/4399730
  • Yahoo — Sender Hub — https://senders.yahooinc.com/
Aarav Sharma

Aarav Sharma

Lead Software Engineer

Aarav leads product engineering at Matlab Infotech, where he has shipped mobile and web platforms across healthcare, fintech, and SaaS. He writes about pragmatic engineering and shipping fast without cutting corners.

Let's Collaborate

Tell us about your project and we'll come back with a plan, a timeline, and a quote.

Project Type

Budget

Task Message

Your Contacts