惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The GitHub Blog
The GitHub Blog
IT之家
IT之家
B
Blog RSS Feed
罗磊的独立博客
GbyAI
GbyAI
博客园 - Franky
Y
Y Combinator Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Google DeepMind News
Google DeepMind News
博客园 - 聂微东
N
Netflix TechBlog - Medium
博客园 - 三生石上(FineUI控件)
人人都是产品经理
人人都是产品经理
U
Unit 42
博客园 - 叶小钗
Jina AI
Jina AI
MyScale Blog
MyScale Blog
雷峰网
雷峰网
B
Blog
Hugging Face - Blog
Hugging Face - Blog
Blog — PlanetScale
Blog — PlanetScale
Recent Announcements
Recent Announcements
腾讯CDC
酷 壳 – CoolShell
酷 壳 – CoolShell

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
WordPress Emails Were Failing Silently on DigitalOcean. H...
Mike Kipruto · 2026-05-31 · via DEV Community

WordPress Emails Were Failing Silently on DigitalOcean. Here's What Broke.

I run a WordPress site on a DigitalOcean droplet handling contact forms, service requests, and automated notifications.

Everything worked in development.

In production, emails started disappearing without errors on the frontend.

No alerts. No logs. Just missing messages.

The issue wasn't WordPress.

It was the environment it was running in.

Here's what actually broke and how I rebuilt the system to make email delivery reliable.

SMTP Worked Locally but Failed in Production

Locally, SMTP with Zoho worked perfectly:

  • Credentials were valid
  • Emails were delivered
  • No errors appeared

After deploying to DigitalOcean, SMTP failed immediately.

Connections to Zoho's SMTP servers never succeeded.

The problem wasn't WordPress or the credentials.

DigitalOcean blocks outbound SMTP ports by default as an anti-abuse measure.

WordPress never even reached the mail server.

What looked like a WordPress issue was actually a network restriction.

Switching to Zoho API Solved One Problem and Revealed Another

Zoho provides two ways to send email:

  • SMTP
  • Mail API v2 (HTTPS-based)

The API immediately solved the network problem because HTTPS traffic is allowed.

But new constraints appeared.

The API Enforces Stricter Rules Than SMTP

Sender Identity Must Be Verified

With SMTP, you can often send from multiple addresses.

With the Zoho Mail API, the sender must be a verified account.

If the authenticated account is admin@example.com, sending as contact@example.com may fail unless that address is verified.

Fix:

Use the authenticated Zoho account as the sender address and customize only the display name.

Reply-To Does Not Behave Like SMTP

This created a challenge for contact forms.

SMTP generally accepts arbitrary Reply-To addresses.

The Zoho API can reject unverified Reply-To addresses and fail the entire request.

Fix:

Instead of relying on Reply-To:

  • Include the user's email address in the message body
  • Add a clickable mailto reply link

Less elegant, but significantly more reliable.

Local Testing Created a False Sense of Reliability

Everything worked locally.

That led to a dangerous assumption:

  • SMTP was stable
  • WordPress email delivery was working correctly

Production environments introduce variables local development doesn't:

  • Port restrictions
  • Firewall policies
  • Hosting-level blocks

Email delivery should always be validated under production conditions.

Silent Email Failures Are the Worst Kind of Failure

Many WordPress plugins display a success message even when email delivery fails.

This creates a dangerous gap:

  • Users think their message was sent
  • Site owners never receive notifications
  • Failures remain invisible

I changed the design approach completely.

In my setup:

  • Failures are logged
  • Alerts are sent to Telegram
  • Form submissions remain stored even if email delivery fails

Email became a notification layer, not the system of record.

The Real Fix: A Transport Layer That Makes Decisions

Instead of relying on a single delivery method, I built a routing layer.

Default Path

Use the Zoho Mail API for transactional emails because it works reliably on DigitalOcean.

Fallback Path

Switch to SMTP when attachments are required or API delivery is unavailable.

Failure Handling

Authentication and configuration failures trigger immediate alerts.

The architectural shift was simple:

WordPress no longer decides how email is sent. The transport layer does.

Deliverability Depends on DNS Too

After delivery was working, I verified authentication through Gmail headers.

Everything passed:

  • SPF
  • DKIM
  • DMARC

These checks confirm:

  • The domain is authorized to send mail
  • Messages are cryptographically signed
  • Receiving servers are more likely to trust the email

Without proper DNS authentication, even successfully sent emails may land in spam.

What Broke and How It Was Fixed

Problem Fix
DigitalOcean blocked SMTP ports Switched to Zoho Mail API
Sender validation failures Used verified sender accounts
Reply-To restrictions Embedded reply information in messages
Local testing missed production issues Tested under real production conditions
Silent failures Added logging and Telegram alerts
Single delivery path Built a hybrid transport layer

Final Takeaway

Most WordPress email problems are not WordPress problems.

They're infrastructure problems.

Once you account for:

  • Network restrictions
  • API enforcement rules
  • Failure visibility
  • Email authentication

Delivery becomes predictable.

The goal isn't choosing a better email tool.

The goal is designing for failure from the start.


I documented the full implementation, architecture, and production setup on my site:

https://mike.co.ke/wordpress/zoho-mail-digitalocean-email-delivery-fixes/