Repository navigation
Description
Describe the bug
The email field can contain a double dot (..), which makes it an invalid address. For example:
{
"name": { "title": "Mr", "first": "Hans-J.", "last": "Schaub" },
"email": "hans-j..schaub@example.com"
}hans-j..schaub@example.com is not a valid email address — the local part contains an empty label between two dots. Any consumer that validates the field with a standard email format (e.g. zod.email(), validator.js, Django's EmailValidator) will reject the entire response payload, not just the one record. That makes a single affected user enough to break a client that fetches a batch.
Root cause
The email is assembled in api/1.4/api.js:177:
this.include('email', tr.transliterate(`${name[0]}.${name[1]}`).replace(/ /g, '').toLowerCase() + '@example.com');The first and last name are joined with a ., and the name is otherwise only stripped of spaces and transliterated. Nothing removes a dot that is already part of the name, so a name that itself ends in a . produces two consecutive dots.
There are exactly four such entries in the shipped name lists, all German male first names in api/1.4/data/DE/lists/male_first.txt:
| line | name | generated email |
|---|---|---|
| 370 | Hans D. |
hansd..schmidt@example.com |
| 392 | Hans-H. |
hans-h..schmidt@example.com |
| 399 | Hans-J. |
hans-j..schaub@example.com |
| 613 | Klaus-D. |
klaus-d..schmidt@example.com |
How to reproduce
Reproduce the generator locally against the affected name:
const transliterate = (s) => s.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
const build = (first, last) =>
transliterate(`${first}.${last}`).replace(/ /g, '').toLowerCase() + '@example.com';
build('Hans-J.', 'Schaub'); // -> 'hans-j..schaub@example.com'Or hit the live API repeatedly until one of the affected German male names is drawn:
for i in $(seq 1 200); do
curl -s "https://randomuser.me/api/?results=100" \
| jq -r '.results[] | select(.email | test("\\.\\.")) | "\(.name.first) | \(.email)"'
sleep 0.5
doneFrequency
Roughly 1 in 3000 users returned by the API has a malformed email:
- 4 affected names out of 1025 entries in
DE/lists/male_first.txt→ 1 in 256 German male users - German users are ~1/21 of a mixed-nationality payload, and ~1/2 of those are male
- So a payload of 100 users contains a malformed email roughly 1% of the time
Observed over 3000 live users: 1 occurrence (hans-j..schaub@example.com, from Hans-J. Schaub, nat DE).
Suggested fix
Collapse consecutive dots in the local part after the name is joined, so the separator is not duplicated:
const local = transliterate(`${name[0]}.${name[1]}`)
.replace(/ /g, '')
.replace(/\.{2,}/g, '.') // collapse duplicate separators
.toLowerCase();
this.include('email', local + '@example.com');Alternatively, strip trailing dots from the name before joining. Fixing the four data entries alone would also resolve the current occurrences, but the generator would still emit a malformed address for any future name containing a dot, so guarding in the generator is the more durable fix.
Impact
Clients that validate the response against a schema are affected disproportionately, because validation is all-or-nothing per payload: one malformed address in a batch of 100 rejects all 100 users. Clients that read the field as a plain string are unaffected.
I hit this while consuming the API behind a Zod schema — the strict zod.email() check rejected the whole payload, so the UI rendered an empty list instead of the 100 users that were actually returned.
Activity