For developers
The test address in your CI belongs to somebody
16 July 2026 · 2 min read · TMailr
Test data is usually harmless. Email addresses in test data are not, because unlike a fake name or a made-up postcode, an address is a destination, and something will eventually send to it.
The domains that are safe
RFC 2606 reserves example.com, example.net, example.org and the .test, .invalid, .example and .localhost top-level domains. These exist precisely so that a test can name an address without naming a person. Nobody receives mail there, and nobody can register them.
Everything else belongs to somebody. test@gmail.com is an account. john@company.com is probably a person at a real business who did not agree to be in your fixtures.
How it goes wrong
- A staging environment points at the production mail relay for an afternoon and a hundred test messages reach real inboxes.
- A seed script with realistic-looking addresses is run against production by somebody who thought they were on staging.
- A load test with generated addresses at a real domain becomes a small, unintentional dictionary attack.
- A screenshot in your documentation shows a real address, and it gets scraped.
Each of these is a version of the same mistake: an address in a fixture was treated as a string rather than as somebody’s mailbox.
Reserved domains are not enough on their own
They stop you reaching a stranger. They do not let you test that mail actually works, because nothing receives at example.com either. That is the gap a sandbox fills: a domain where every address exists and belongs to you, so a test can send for real and read the result.
Use both. Reserved domains for fixtures that never send, a sandbox for the tests that do.
Practical rules
- Fixtures and seeds use example.com or .test, without exception.
- Tests that send use a sandbox domain you control, with the address derived from the test name so runs cannot collide.
- Non-production environments cannot reach the real world: a relay that refuses external recipients turns a bad afternoon into a log line.
- Anonymise addresses when copying production data down, and treat any copy that still contains real ones as production.
- Documentation and screenshots use reserved domains too.
The one that catches everyone
The environment variable that decides where mail goes is the single most important line of configuration in a non-production system, and it is usually inherited from a template nobody has read since the service was created. It is worth confirming what your staging environment would do if it tried to send right now, rather than finding out from a stranger.
More on for developers