Skip to content
Engineering

Email Addresses in Automation: Validation and Edge Cases

| | 10 min read
Email Addresses in Automation: Validation and Edge Cases
Email Addresses in Automation: Validation and Edge Cases

Email is one of the oldest “APIs” on the internet, and it still sits in the critical path for onboarding, password resets, alerts, and identity workflows. That makes email addresses a surprisingly high leverage surface area for automation: if your validation is too strict, you block real users and generate support tickets. If it is too lax, you ship flaky tests, leak data, or open up injection vulnerabilities.

For AI agents and LLM-driven automations, the problem gets harder: agents often extract addresses from messy text, then act on them across systems with different rules. This guide covers practical validation layers and the edge cases that most commonly break automated flows.

What “valid” means (and why teams disagree)

In production and in test harnesses, “valid email address” can mean at least four different things:

Meaning of “valid” What you are actually checking Where it belongs Common failure mode
Syntactically valid The string can be parsed as an email address Client and API boundary Overly strict regex rejects legitimate addresses
Routable domain Domain has DNS records (often MX, sometimes A/AAAA) Server side Treating “no MX” as always invalid (some domains accept mail on A/AAAA)
Deliverable mailbox A mailbox exists and accepts mail Only via sending a message (verification) SMTP “probe” logic gets blocked, rate limited, or violates policy
Acceptable for your product Your product-specific rules (no role accounts, no plus tags, etc.) Product layer Product rules accidentally break enterprise or international users

The key automation lesson: separate parsing from policy. Parse addresses with a real parser, then apply your business rules explicitly.

Standards vs reality: the gap that causes edge cases

If you validate against the full grammar of email, you will accept addresses many systems never see in practice. If you validate only “what Gmail accepts,” you will reject a lot of real addresses.

Useful references for what is allowed at the protocol level:

  • RFC 5322 (message format, mailbox syntax)
  • RFC 5321 (SMTP, including length constraints)
  • RFC 6531 (SMTPUTF8 for internationalized email)

Also note that many frontends rely on the HTML “email” input type, which is intentionally permissive and not a full RFC validator. See the WHATWG HTML spec for type="email".

Practical constraints you should enforce

These constraints are widely used and align with SMTP limits:

  • Total length: 254 characters max is the commonly enforced limit derived from SMTP constraints (a practical ceiling used by many systems).
  • Local part length: 64 characters max.
  • No control characters: especially \r and \n.
  • Trim surrounding whitespace: but do not silently remove internal whitespace.

Even if your parser can accept more, enforcing these limits prevents downstream failures in vendors, CRMs, and transactional email providers.

Edge cases that break automation (and what to do about them)

Most flaky “email tests” are not about sending email. They are about address interpretation differences across systems.

1) Plus addressing (subaddressing)

Example: [email protected]

  • Many providers route +tag to the same mailbox, which makes it great for automation and correlation.
  • Some corporate systems and legacy identity providers reject +.

Automation guidance: If you control address generation for tests, keep a configurable strategy: prefer plus tags for correlation, but be able to fall back to simple runid-uuid@domain.

2) Dot normalization (Gmail-specific behavior)

Example: [email protected] and [email protected] are equivalent in Gmail, but not in most other systems.

Automation guidance: Never assume dots are ignored. Treat the full local part string as the identifier unless you are applying a provider-specific rule intentionally.

3) Case sensitivity in the local part

Technically, the local part can be case-sensitive, but almost all modern providers treat it as case-insensitive.

Automation guidance: Store the original for display, but compare using a normalized form you define (typically lowercasing the domain, and optionally the local part if your product treats it as case-insensitive). Make this a deliberate policy decision.

4) Quoted local parts (valid but rarely supported)

Example: "john..doe"@example.com (yes, quotes can change what is allowed)

Automation guidance: Decide early whether to support quoted local parts. Many SaaS products intentionally reject them to reduce complexity. If you reject them, document it and return a clear error.

5) Internationalized email (EAI) and IDNs

Examples:

  • Local part with Unicode: miyuki.さくら@例え.テスト (requires SMTPUTF8 support)
  • Internationalized domain names: user@bücher.example (often converted to punycode internally)

Automation guidance: Supporting IDNs (Unicode domains) is easier than supporting Unicode local parts. If you do accept Unicode domains, convert them using an IDNA library and validate the ASCII (punycode) form for DNS checks.

6) Domain literals

Example: user@[192.168.1.10]

These are syntactically valid in some contexts but are almost never acceptable in consumer signup.

Automation guidance: Reject domain literals unless you have a specific enterprise use case. They complicate security review and can create surprising routing behavior.

7) Display names and angle brackets (common in extraction)

Example: Jane Doe <[email protected]>

Humans write this format constantly, and LLMs often output it when summarizing.

Automation guidance: Your input validation can reject it, but your extraction pipeline should handle it. Use a parser that can extract the addr-spec portion rather than a regex.

8) Trailing punctuation from natural language

Examples:

Automation guidance: When extracting from text, strip surrounding punctuation after parsing, not before. Otherwise you risk turning [email protected] into something else.

9) Multiple addresses in one field

Example: [email protected], [email protected]

This shows up when agents read “cc these people” instructions.

Automation guidance: Treat “single email” fields as single, and fail loudly. If you support lists, model them as arrays at the API layer.

A validation pipeline that works for humans, bots, and agents

A robust approach is layered, with each layer answering one question.

A simple five-step pipeline diagram showing: 1) normalize input, 2) parse address, 3) enforce length and character policy, 4) optional DNS check, 5) verification email and inbox observation. Each step is a labeled box connected left to right.

Layer 1: Normalize (without changing meaning)

Recommended normalization for automation:

  • Trim leading and trailing whitespace.
  • Convert the domain to lowercase.
  • If you accept IDNs, convert Unicode domain to ASCII (punycode) for storage and DNS.
  • Do not remove dots or plus tags unless you explicitly implement provider-specific behavior.

Layer 2: Parse, do not regex

Email regexes are notorious for false positives and false negatives. Prefer a well-maintained email parsing library in your language that can:

  • Parse addr-spec correctly
  • Reject control characters
  • Handle common extraction formats (Name <email@domain>)

Layer 3: Apply product policy

Keep policy checks explicit and testable:

  • Allow or disallow plus addressing
  • Allow or disallow quoted local parts
  • Allow or disallow Unicode local part
  • Blocklists (temporary domains, known role accounts) if your product requires it

Layer 4: Optional DNS check (helpful, not definitive)

A DNS lookup can catch obvious typos like gmial.com, but it is not a guarantee of deliverability.

Practical rules:

  • Treat DNS checks as a hint for UX (for example, “did you mean…?”).
  • Do not block signups solely on “no MX” unless your requirements justify it.

Layer 5: Verification is the only real deliverability test

If you need to know the mailbox is real, the only reliable method is sending a verification email (magic link or OTP) and requiring the user or workflow to complete it.

In automated environments (CI, QA, agent runs), this is where deterministic inbox tooling matters. Mailhook’s approach is to create disposable inboxes via API and receive messages as structured JSON (with webhooks or polling), which makes verification flows testable without brittle HTML parsing. For the up-to-date, canonical feature list, reference the product’s llms.txt.

Edge cases in test automation: making failures explainable

Validation bugs are painful, but automation failures are worse when you cannot explain them. The goal is to make every email-related failure actionable.

Correlate addresses to runs, not people

In tests and agent workflows, generate addresses that are clearly tied to a run identifier:

  • Include a short run id in the local part when allowed (for example, plus tags or a delimiter).
  • Avoid leaking customer-like identifiers into logs.

This makes it easy to answer: “Which run generated this email?” without digging through HTML bodies.

Model retries and duplicates

Verification systems frequently resend. Your harness should expect:

  • Duplicate OTP emails
  • Out-of-order arrival
  • Multiple templates (welcome email plus verification email)

Instead of asserting “the first email is the verification,” assert on stable fields (recipient, subject patterns, presence of a link token), and make your code idempotent.

Agent workflows: extraction and document-heavy pipelines

LLM agents often sit upstream of your validation logic. They might extract email addresses from PDFs, chat logs, intake forms, or long email threads. In these contexts, you want a two-stage process:

  1. Extract candidates (possibly multiple) with provenance (where it came from).
  2. Validate and select using your parsing and policy rules.

This is especially relevant in document-heavy domains. For example, legal teams using tools like TrialBase AI to generate litigation materials from case files may need reliable contact extraction before sending demand letters or requests. Automations that treat “Jane Doe [email protected]” as invalid without extracting the address will break at exactly the moment speed matters.

Security and reliability pitfalls (easy to miss)

Even if you are “just validating an email,” the string is untrusted input.

  • Header injection: Always reject or escape \r and \n to prevent attackers from injecting extra headers when the value is later used in email-sending code.
  • Regex performance: Some complex email regexes are vulnerable to catastrophic backtracking. Use parsers or simple bounded checks.
  • Logging and privacy: Treat email addresses as personal data. Log hashes or redacted forms when possible.
  • Normalization surprises: If you normalize aggressively (dots, plus tags), you can accidentally merge distinct accounts for non-Gmail domains.

For general input validation guidance, OWASP’s Input Validation Cheat Sheet is a solid baseline.

A practical checklist for teams shipping automation

Use this as a final review for your email address handling:

  • Your system uses a parser, not a single regex, for core validation.
  • You enforce length limits and reject control characters.
  • You separate “syntactically valid” from “deliverable,” and use verification for deliverability.
  • Your extraction pipeline can handle Name <email@domain> and trailing punctuation.
  • Your policy decisions (plus tags, quoted local parts, Unicode) are explicit and documented.
  • Your tests generate unique, run-correlated addresses and tolerate resends and out-of-order emails.

If your automations depend on email verification, the final step is always observability: you need to reliably see what was sent, to which address, and when, and to consume it in a machine-friendly format.

Related Articles