Point staging at a mail catching server instead of the internet, use reserved example addresses for test users, and add an outbound allowlist as a second guard. Then test with a canary message. Together these make it close to impossible for a staging job to reach a real customer.
How these incidents happen
A team copies a database, restarts the scheduled jobs, and a reminder email goes to every customer on the list. The root cause is rarely malice. It is a staging environment that still has working mail settings and real addresses.
Even with synthetic data, address generators can produce real looking emails. The Faker documentation warns that its standard email method may coincidentally produce real addresses and recommends its example email method when that matters.
The three layers
| Layer | What it does | Fails when |
|---|---|---|
| Reserved test addresses | Addresses at example.com style domains cannot belong to real mailboxes | Fixtures use other domains |
| Mail catcher | All outbound SMTP lands in a local inbox | An app uses an API provider instead of SMTP |
| Allowlist | Only listed recipients can ever be sent to | Someone adds a wildcard |
Steps
- Switch staging to a catch tool. Tools such as Mailpit act as an SMTP server that captures messages and shows them in a web interface, with an API for integration tests. Set the application's SMTP host to it in staging configuration only.
- Remove production mail credentials. Staging should not hold the live provider key. Without the key, a misrouted send fails rather than delivers.
- Use reserved addresses. See the related post on safe email domains for test data.
- Add an allowlist in code. In the mail sending wrapper, when the environment is not production, drop any recipient not on a short list of team addresses. Log what was dropped.
- Cover other channels. SMS, push notifications, webhooks and chat messages need the same treatment. Use provider test modes and sandbox keys.
- Disable scheduled jobs on restore. After any copy or restore, jobs should start paused until someone checks the environment.
- Send a canary. Trigger one email to an address like canary at example.com and confirm it lands in the catcher and nowhere else.
About relaying
Some catch tools can release a captured message to a real SMTP server so you can check true delivery. Mailpit documents relaying with an optional allowlist of accepted recipients. If you use that feature, keep the allowlist narrow, limited to mailboxes your team owns.
Mistakes to avoid
- Configuring the mail catcher in one service and forgetting a worker that sends with its own settings.
- Using a real customer address "just to see how it looks".
- Leaving the mail provider's production webhook pointing at staging.
- Assuming a provider sandbox mode applies to all message types without testing.
Quick check
Do I need this if staging uses fake data?
Yes. Fake data can still contain real looking addresses, and old configuration may still hold live credentials. The cost of a guard is small.
What if I need to test real delivery?
Use mailboxes your team controls, on a short allowlist, and send only from a clearly labelled staging sender.
Sources
Last reviewed: 19 October 2026.