DEV Community

Cover image for The part Cloudflare Email Routing doesn't solve — and how I fixed it
nonozone
nonozone

Posted on

The part Cloudflare Email Routing doesn't solve — and how I fixed it

Cloudflare Email Routing is genuinely good. Free, reliable, zero infrastructure to manage. You point your MX records at Cloudflare, configure a few rules, and emails sent to support@yourdomain.com start appearing in your Gmail inbox within minutes.

If all you need is to receive email at a custom domain, it's hard to beat.

The problem starts when you hit reply.


What forwarding actually does

When Cloudflare forwards a message from support@yourdomain.com to your personal Gmail, it doesn't just move the email. It rewrites the envelope.

The original SMTP transaction looked like this:

Enter fullscreen mode Exit fullscreen mode

After forwarding, the message arrives in your Gmail with extra headers like X-Forwarded-To and X-Original-To that record where it originally went. But your Gmail client doesn't read those headers. It sees one thing: this email arrived at your Gmail address.

So when you hit reply, your email client does the obvious thing — it replies from your Gmail address.

Your customer, who wrote to support@yourdomain.com, now gets a reply from yourname@gmail.com.

That's the gap. Cloudflare solved receiving. Nobody solved replying.


The obvious workarounds (and why they fall short)

1. Add a "Send As" alias in Gmail

Gmail lets you add custom From addresses via SMTP. So you add support@yourdomain.com as a Send As alias, pointing at a transactional SMTP provider.

This works — until you have more than one or two addresses. When you're managing support@, sales@, admin@, billing@ across two or three domains, you now have to:

  • Manually pick the correct From address every time you reply
  • Remember which address the customer originally wrote to
  • Hope you don't reply from the wrong one

At some point you will mis-send. A support@ customer gets a reply from founder@. A sales@ prospect gets a reply from your personal address. The professional illusion collapses.

2. Set up separate mailboxes per address

This is the traditional solution — buy a Google Workspace seat (or Fastmail, or Zoho) for each address. It works, but now you're paying per identity, not per person, and you're context-switching between inboxes all day.

If your address count grows faster than your headcount — which is common for small studios, agencies, and solo operators — this gets expensive fast.


What actually needs to happen

The root problem is that forwarded email loses its routing context by the time it reaches your client. To reply correctly, something needs to:

  1. Preserve the original recipient address when forwarding
  2. Read that context when you hit reply
  3. Rewrite the envelope on outbound — so the SMTP MAIL FROM and the visible From: header show support@yourdomain.com, not your personal address

Step 3 is the key one. It's called envelope rewriting, and it's what makes the difference between "email forwarding" and "identity routing."

The flow looks like this:

Customer
  → support@yourdomain.com
  → Cloudflare Email Routing (inbound MX)
  → Relay layer (preserves routing context in headers)
  → Your working inbox (Gmail / Outlook / Apple Mail)

You hit reply
  → Mail client sends to relay's SMTP
  → Relay reads X-Original-To header
  → Relay rewrites MAIL FROM to support@yourdomain.com
  → Customer receives reply from support@yourdomain.com ✓
Enter fullscreen mode Exit fullscreen mode

Your client sees one SMTP connection. You configure it once. After that, every reply automatically goes out from whatever address the original email was sent to — no manual selection, no switching, no mistakes.


Building this

I run a small one-person studio with a few projects, each with its own domain. I got tired of either paying per mailbox or manually managing Send As aliases. So I built a relay layer that sits between Cloudflare Email Routing and my working inbox.

The inbound side was straightforward: Cloudflare already stamps X-Forwarded-To and X-Original-To on every forwarded message. I just needed to make sure those headers survived into my inbox intact.

The outbound side was the real work. When you provide custom SMTP credentials to a mail client, the client hands off full control of the outgoing message. That's where envelope rewriting happens — inspect the message for routing context, determine the correct sender identity, rewrite the headers, and relay to the upstream MTA.

A few things that made this interesting to get right:

  • Sender verification: You can't let anyone claim any From address. The relay has to know which addresses are authorised for which accounts.
  • Header precedence: Mail clients sometimes set Sender: and Reply-To: in ways that conflict. Getting the priority chain right takes care.
  • Bounce handling: When a rewritten outbound message bounces, the bounce goes to MAIL FROM — which is now your domain address. You need to route those back correctly.

The result

After setting this up, the workflow became:

  • All domain email lands in one inbox
  • Hit reply — correct sender, every time, automatically
  • No manual address selection
  • No per-seat mailbox costs
  • No context switching

I called the tool OhRelay and opened it up to early access: ohrelay.com

It works on top of Cloudflare Email Routing, so if you're already using that for inbound, setup is mostly just DNS and one SMTP config in your mail client. The guide covers Gmail, Outlook, and Apple Mail.


If you've been living with the wrong-sender problem or managing too many mailbox seats, it might be worth a look. Happy to answer questions in the comments about how the relay layer works — it's an interesting corner of email infrastructure that doesn't get talked about much.

Top comments (0)