Skip to content

Email validation rejects valid modern gTLDs (.rocks, .radio, .app) due to legacy validator default #26197

@bobbymac

Description

@bobbymac

Bug Description

Ghost's email validation rejects legitimate email addresses using newer generic Top-Level Domains (gTLDs) like .rocks, .radio, .app, and other TLDs approved by ICANN after 2012.

Expected Behavior

Email addresses like user@example.rocks or user@example.radio should be accepted as valid.

Actual Behavior

These emails are rejected during member signup/newsletter subscription.

Root Cause Analysis

I traced this to @tryghost/validator:

The issue: The isEmail function defaults to legacy: true, which uses validator@7.2.0 (from 2017):

// packages/validator/lib/validator.js
validators.isEmail = function isEmail(str, options = {legacy: true}) {
    if (!options?.legacy) {
        return isEmailCustom(str);  // Modern validator - WORKS
    }
    return baseValidator.isEmail(str);  // validator@7.2.0 - BROKEN for new TLDs
};

Dependency chain:

ghost/core
└── @tryghost/validator@0.2.17
    └── validator@7.2.0  ← Problem (2017, predates many gTLDs)

The irony: Ghost already has a modern validator built-in (lib/is-email.js, copied from validator.js v13.7.0) — it just isn't used by default.

Suggested Fix

Change the default from legacy: true to legacy: false:

// packages/validator/lib/validator.js
validators.isEmail = function isEmail(str, options = {legacy: false}) {

This would make Ghost use the modern custom validator that properly handles all TLDs.

Alternative Fixes

  1. Update validator dependency from 7.2.0 to 13.x+
  2. Remove the legacy codepath entirely

Environment

  • Ghost version: 6.16.1
  • @tryghost/validator: 0.2.17
  • validator (bundled): 7.2.0

Additional Context

The .rocks TLD has been active since 2014, .radio since 2017. Both are legitimate ICANN-approved gTLDs with real users who can't subscribe to Ghost newsletters.

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs:info[triage] Blocked on missing information

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions