Email routing looks simple until it is not. You point a domain at a mail server, mail arrives, everyone is happy, and then one day a customer says « I emailed you last week and got a bounce » and you discover that half your published addresses were never real mailboxes at all. The fixes are not exotic. They are five routing decisions, and here is the part most guides skip: each one is independent, and failing any single one breaks the chain even if the other four are perfect. Get all five right and domain mail keeps working through provider changes, migrations and the occasional 3 a.m. incident.
Publish explicit aliases and treat a catch-all as a deliberate exception
Start with the myth worth busting first: a catch-all email address is not a shortcut for « make every address work. » A catch-all email accepts every message sent to a domain, whether or not anyone planned for that address. That sounds generous, and in a few narrow cases it is. But a catch-all is not an alias, not forwarding, and not a disposable address system, and conflating those things is how domains end up quietly digesting spam aimed at addresses nobody ever published.
The safer default is the boring one. Anything you publish on a website, a business card, an invoice or a social profile gets an explicit alias that points at a real mailbox. sales@, support@, billing@, press@ and the personal addresses your team actually uses should all be defined by name on the mail server. When a message arrives for an address that has no mailbox and no alias, a standard mail server replies with 550 no such user. That bounce is a feature. It tells the sender they typed the wrong address, and it tells you that nobody is silently absorbing mail for a typo like suport@ that a spammer scraped from a PDF.
Where does a catch-all earn its place? Catch-all domains are used for unlimited unpredictable addresses in automation and sign-ups: per-service addresses like github@yourdomain or receipts@yourdomain so you can trace who leaked your address, or a testing workflow where addresses are generated on the fly. If you run one, own the trade-off. Catch-all carries the risk of accepting spam to invented addresses, and the inbox behind it becomes a junk magnet within weeks. The rule that keeps this sane: run a catch-all only if you will actually review it, with a filter or a scheduled sweep, and never point it at the mailbox a human depends on for real correspondence.
Aliases, forwarding and catch-alls are three different tools
Catch-all vs email forwarding is another distinction people flatten. Forwarding takes mail for one defined address and relays it elsewhere; an alias is a defined name that resolves to a mailbox or list; a catch-all is the wildcard rule that catches everything left over. Only the first two are explicit. If a new hire needs firstname@yourdomain, that is an alias decision made on purpose, not something you hope the wildcard will cover. The moment you rely on the catch-all to make published addresses work, you have lost track of which addresses are real, and the next migration will expose it.
Point one authoritative MX at a server that actually accepts unknown recipients
Here is the myth that causes the most wasted afternoons: people assume a catch-all is a DNS setting. It is not. A catch-all email is configured on the mail server, not in DNS. MX records route inbound mail to a mail server, and that is all they do. They tell the sending world where to deliver; they do not tell the receiving server what to do with an address it does not recognize. You can publish a perfect MX record and still get 550 no such user for every unlisted address, because the server at the other end has no fallback rule configured. Understanding how catch-all email works means understanding that split: DNS gets the mail to the door, the server decides who gets in.
A working catch-all setup requires DNS pointing at the right host and a server accepting unknown recipients. Both halves, or nothing. If you use Cloudflare for DNS, the MX record points at your mail host, and Cloudflare’s own email routing is a separate feature that forwards to verified destinations; if you enable catch-all there, that is Cloudflare accepting unknown recipients on your behalf, not your own server. read more is worth a closer look. If you run cPanel, the catch-all setting lives in the Email Deliverability or Default Address area and pipes unmatched mail to a chosen mailbox, and it only matters once MX points at that cPanel host. On Postfix the equivalent is a virtual alias map ending in a catch-all entry, and on Exim it is a router with a wildcard local part. Same idea in all three: the wildcard mailbox is a server-side rule, and MX is just the address on the envelope.
The second half of this decision is authority. One MX target, or one provider’s set, should be the authoritative destination for the domain. Split delivery across two unrelated providers and you get mail landing in two inboxes with two sets of filters, two spam policies and two copies of the same conversation. During a migration, lower the TTL on your MX records a day or two ahead, cut over cleanly, and keep the old provider receiving for a short overlap window only if you have a documented way to reconcile both inboxes. A domain with ambiguous MX is a domain where « I never got your email » is unfalsifiable.
Align SPF, DKIM and DMARC at the provider and write down the fallback
Now the myth that ties the whole chain together: people believe SPF, DKIM and DMARC govern whether mail arrives. They govern outbound mail only. They are your domain’s claim about who may send as you, and receiving servers check them on the way out of your infrastructure, not on the way in. Tightening DMARC will not fix a broken catch-all, and a perfect catch-all will not save you if your outbound mail fails alignment. Two directions, two separate jobs.
The practical rule is that SPF, DKIM and DMARC must be aligned at the provider that actually sends your mail. If your MX points at one host but your transactional email leaves through another, that second sender needs its own SPF include and its own DKIM signature with the domain aligned in the From header. Keep the SPF record under the ten-lookup limit, sign with DKIM at 2048-bit keys where the provider supports it, and move DMARC from p=none to p=quarantine and then p=reject once your reports show only legitimate sources. A catch-all mailbox does not change any of this, but it does mean you should watch inbound spam scores more closely, because a wildcard that accepts everything is also a wildcard that accepts forged mail addressed to invented locals.
Then document the fallback for unknown recipients, because this is the decision everyone forgets until it bites. Write down, in one place, what happens when mail arrives for an address that matches no mailbox and no alias. Is there a catch-all, and if so which mailbox does it feed and who reviews it? If there is no catch-all, is the 550 no such user response intentional, and does your support team know that a customer reporting a bounce on a published address means an alias is missing? Include the answer to « what if the catch-all mailbox fills up or the reviewer leaves » too. The fallback rule mail server behavior is a policy choice, and a policy nobody wrote down is a policy nobody can debug at 2 a.m. during a provider outage. AllMail.one publishes a guide to catch-all email that covers the server-side settings for the common stacks, which is a reasonable starting point for writing your own version down.
None of these five decisions is hard on its own. Explicit aliases for anything published, a catch-all only if you will review it, one authoritative MX target, SPF/DKIM/DMARC aligned at the provider that sends, and a documented fallback for unknown recipients. The trap is treating them as one project instead of five independent switches. Audit them separately this week: list every published address and confirm each has an alias, check whether a catch-all exists and who reads it, trace your MX to a single authority, pull your DNS records and confirm alignment, and write the fallback paragraph into your runbook. Fix whichever one is broken first, then re-test with a real send to a real address and a deliberate typo. The bounce, or its absence, will tell you the truth.