Skip to content

Regex for Email Validation? Think Again!

Sponsor: Using RabbitMQ or Azure Service Bus in your .NET systems? Well, you could just use their SDKs and roll your own serialization, routing, outbox, retries, and telemetry. I mean, seriously, how hard could it be?

Learn more about Software Architecture & Design.
Join thousands of developers getting weekly updates to increase your understanding of software architecture and design concepts.


I ran into a nightmare of an issue recently because a service I use changed their email validation and decided my address wasn’t valid. In this post I want to walk through what happened, why simple regex for email validation often causes problems, and what you should do instead if you need to know whether an email actually exists.

YouTube

Check out my YouTube channel, where I post all kinds of content on Software Architecture & Design, including this video showing everything in this post.

The problem: plus-addressing and overzealous validation

If you use Gmail or many other providers, you might be familiar with labels (sometimes called plus-addressing). You can specify your account name, then a plus, then a label. For example, my actual mailbox is derek@codeopinion.com, but I also use addresses like derek+youtube@codeopinion.com so I can filter or have unique addresses for services. There’s no difference in delivery — they all go to the same mailbox — but they are distinct addresses.

A service I used must have changed their application (probably something in their database), and I got an email requesting that I do a “forgot password” flow to reset it. The problem was: when I tried to enter my email address, their new validation wouldn’t even let me submit it because of the plus.

I tried a couple of online validation tools out of curiosity to see what they were doing as regex for email validation and saw the same thing: “Enter an email address. Nope, doesn’t work with the plus. Remove the plus, it validates.” Not great. This is more than just a bad regular expression — it’s conflating format validity with whether a mailbox actually exists.

What is a valid email address (format)?

“A valid email address is as follows: just the local part, an at symbol, then the domain. It’s not more complicated than that.”

To expand that a bit in plain terms:

  • The local part is everything before the @. It can include letters, numbers, dots, and certain special characters — including the plus sign used for labels.
  • The @ symbol separates the local part from the domain.
  • The domain is everything after the @ — a valid hostname (and often requires an MX record for mail delivery).

For simple format validation, you don’t need a monstrous regex that tries to account for every possible nuance. At its core, it’s just local-part@domain. Overly strict regexes often reject perfectly valid addresses like plus-addressed emails.

Does a valid-looking email actually exist?

Format is only half the battle. An address that looks valid might not exist for several reasons:

  • The domain doesn’t exist.
  • There is no MX record for the domain.
  • The domain accepts mail but the specific local part (the mailbox) doesn’t exist.
  • The mailbox exists but is disabled, full, or otherwise unreachable.

Option 1 — Send a verification email

A naive but straightforward approach is to send a verification email with a one-time code or confirmation link. If the user receives it and can enter the code, you know the address routes to a mailbox they control.

But there are trade-offs. If the verification email bounces, you learn the address is invalid — which is good — but outbound mail systems like AWS SES track bounce and complaint rates. If you send lots of messages that bounce, you can quickly harm your sending reputation. I believe SES treats a bounce rate around 2% as the beginning of warning territory, so you can’t be careless with high-volume verification attempts.

Most providers have bounce and complaint hooks and offer suppression lists. With SES you can:

  • Receive notifications for bounces and complaints.
  • Maintain your own suppression list to avoid re-sending to known-bad addresses.
  • Use the provider’s suppression features to keep your reputation clean.

Option 2 — Mailbox validation services

If you need to know whether an email actually exists but you can’t or don’t want to send verification emails (because of bounce rate or reputation concerns), use a mailbox validation service.

These services do the heavy lifting for you. Typical checks include:

  • Validating the domain exists.
  • Looking up MX records for the domain.
  • Connecting to the domain’s SMTP server and, where possible, checking whether the specific mailbox exists.
  • Returning a probabilistic result or verdict indicating whether the mailbox likely exists.

With that result you can decide whether to accept the address, prompt the user, or proceed to send a verification message if you still want to confirm ownership after the mailbox is likely valid.

Putting it together: what should you do?

  1. If you’re only validating format, keep it simple: validate the local part, the @ symbol, and the domain. Don’t reject valid constructs like plus-addressing with an overzealous regex.
  2. If you also need to know that an address exists, decide which trade-offs you accept:
    • Send a verification email and handle bounces and suppression lists carefully (watch your provider’s thresholds).
    • Or use a mailbox validation service to check existence without sending mail, then optionally send a verification email for final ownership confirmation.
  3. Be mindful of customer experience: don’t create friction by rejecting addresses that are valid or commonly used for filtering (like plus-addresses).

Final thoughts

This whole post/video was spurred by my personal experience and hours spent trying to access an account because a service made a simple email validation change. A small change in validation caused a big headache for me and for other customers who rely on plus-addressing.

Join CodeOpinon!
Developer-level members of my Patreon or YouTube channel get access to a private Discord server to chat with other developers about Software Architecture and Design and access to source code for any working demo application I post on my blog or YouTube. Check out my Patreon or YouTube Membership for more info.