/^/
MediumNetworking5 min read

Subdomain Regex

Validates a hostname that includes at least one subdomain label in front of a base domain and top-level domain, such as www.example.com or api.staging.example.co.uk.

#subdomain#domain#networking#hostname#dns#validation

Regex Pattern

^([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.){2,}[a-zA-Z]{2,}$

Pattern Breakdown

Hover over a token to see what it does.

^([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.){2,}[a-zA-Z]{2,}$
TokenMeaning
^Anchors the match to the start of the string
[a-zA-Z0-9]Each label must start with a letter or digit
([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?Optional middle and ending characters of a label, allowing hyphens but never as the first or last character
\.Literal dot separating each label
){2,}The label-plus-dot group must repeat at least twice, guaranteeing a subdomain plus a base domain before the TLD
[a-zA-Z]{2,}Top-level domain of at least two letters, with no digits or hyphens
$Anchors the match to the end of the string

Detailed Explanation

What it does

This pattern validates that a hostname string has at least three dot-separated parts: one or more subdomain labels, a base domain label, and a top-level domain. It rejects bare domains like example.com because they only contain a base domain and TLD without a subdomain.

Why it works

The repeated group ([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.){2,} requires the label-and-dot sequence to occur two or more times before the final TLD segment. A bare domain like example.com only produces one such repetition ('example.'), so the {2,} quantifier forces at least a subdomain label ('www.') plus the base domain label ('example.') to appear, with 'com' left over as the TLD.

Common use cases

  • Detecting whether a hostname is a subdomain of a multi-tenant SaaS platform, like tenant.app.example.com
  • Routing requests based on whether the Host header includes a subdomain segment
  • Validating custom subdomain input in a signup flow, such as choosing a company's subdomain
  • Filtering DNS records to find CNAME or A records that represent subdomains rather than apex domains

Edge cases

  • A deeply nested hostname like a.b.c.example.com matches because the group can repeat more than twice
  • Country-code second-level domains like example.co.uk are matched, with 'example' and 'co' both counted as label repetitions and 'uk' as the TLD
  • Numeric-looking labels like 192.168.1.1 fail because the final TLD segment requires letters only, correctly excluding IPv4 addresses
  • A hostname with an empty label from a double dot, like example..com, fails to match because empty strings cannot satisfy the label pattern

Limitations

  • Does not consult the Public Suffix List, so it cannot tell whether 'co' in example.co.uk is really part of the TLD or a subdomain
  • Does not validate total hostname length limits (253 characters) or punycode-encoded internationalized domains
  • Cannot distinguish a subdomain that is a live DNS record from one that merely matches the string shape
  • Labels starting or ending with a hyphen are correctly rejected, but the regex does not check for other reserved or invalid label sequences

Interactive Tester

Edit the pattern or text below — matching runs live in your browser.

www.example.com a.b.c.example.com sub.example.co.uk

Test Cases

Editable — add your own inputs to see if they pass.

InputExpectedResult
Pass
Pass
Pass
Pass
Pass
Pass
Pass
Pass
Pass

Language Variants

Production-ready examples in 12 languages.

const subdomainRegex = /^([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.){2,}[a-zA-Z]{2,}$/;
console.log(subdomainRegex.test('www.example.com')); // true

Common Mistakes

Using {1,} instead of {2,} on the repeated label group, which lets bare domains like example.com incorrectly pass as having a subdomain

Fix: Require at least two label-and-dot repetitions so a subdomain and a base domain are both present before the TLD

Assuming this pattern can identify the 'real' registrable domain in cases like example.co.uk

Fix: Use a Public Suffix List library when you need to distinguish true subdomains from multi-part country-code TLDs

Allowing labels to start or end with a hyphen by using a plain [a-zA-Z0-9-]+ character class for the whole label

Fix: Split the label into first character, optional middle-and-last group, so hyphens are only allowed in the interior

Performance Notes

  • The label group has a bounded {0,61} repetition matching the real DNS label length limit, which keeps backtracking bounded
  • Anchoring with ^ and $ prevents scanning for a match at multiple offsets in a longer string
  • The outer {2,} quantifier on a group containing alternation-free, bounded sub-patterns avoids catastrophic backtracking in practice

Browser Compatibility

EngineSupportedNotes
ChromeYes
FirefoxYes
SafariYes
EdgeYes
Node.jsYes