Skip to main content

dns

Wildcard Subdomains: When to Use Them

Design wildcard DNS without confusing DNS reachability, application host routing, and the one-label coverage of TLS wildcard certificates.

Published
Updated
Reviewed

Source review: Checked against RFC 4592 wildcard DNS processing, RFC 9525 TLS identity matching, current Cloudflare wildcard DNS behavior, and Let's Encrypt DNS-01 guidance.

A wildcard is useful when hostname creation is part of the product workflow: tenant spaces, branch previews, or short-lived review environments. It is unnecessary complexity when a team has six known hosts and can create six explicit records.

The main design trap is treating three different controls as if they were one:

  1. Wildcard DNS decides whether a query receives an answer.
  2. Application routing decides whether that Host header maps to a real project.
  3. TLS certificate matching decides whether the browser accepts the server identity.

One wildcard DNS record does not automatically solve the other two.

First decide whether a wildcard earns its risk

Use a wildcard when all of these are true:

  • hostnames are created often enough that per-name DNS changes are an operational bottleneck
  • a trusted controller knows which names are active
  • the edge or application rejects unknown hosts
  • certificate issuance and renewal cover the exact hostname depth
  • every generated host has an owner and expiry rule

Prefer explicit records when names are few, authority-bearing, or long-lived. login, billing, status, and canonical documentation surfaces deserve explicit ownership instead of falling through a catch-all. Use the subdomain naming worksheet to establish that ownership first.

DNS wildcard matching is tree-based

Suppose the zone contains:

*.preview.example.com.  300  IN  CNAME  preview-router.example.net.

A query for branch-482.preview.example.com can be synthesized from that wildcard when no more specific existing name changes the lookup path.

RFC 4592 describes this using the closest encloser: the longest existing ancestor of the queried name. The only wildcard considered is the * label immediately below that closest encloser. Resolvers do not keep searching other wildcard records if that source does not exist.

That produces two operational rules:

  • an exact record at the queried name takes precedence over a wildcard answer
  • an existing node, empty non-terminal, or delegation can change which wildcard is eligible and can stop a broader wildcard from applying below it

Cloudflare documents *.example.com as multi-level by default when no specific record takes precedence, so it may answer both app.example.com and branch.preview.example.com. That DNS behavior is provider- and tree-sensitive; test the authoritative service you actually use instead of assuming the asterisk means a simple one-label string substitution.

For a preview system, a narrower wildcard communicates intent better:

preview.example.com.    300  IN  A      192.0.2.10
*.preview.example.com.  300  IN  CNAME  preview-router.example.net.
docs.example.com.       300  IN  CNAME  canonical-docs.example.net.

The explicit docs record stays outside the preview catch-all. The preview apex has its own behavior, and generated names live beneath preview.example.com.

TLS wildcard matching is deliberately narrower

DNS wildcard behavior and certificate wildcard behavior are not the same. RFC 9525 limits a certificate wildcard to the complete left-most label, and that wildcard matches exactly one label.

Certificate identifierMatchesDoes not match
*.example.comapp.example.comexample.com, branch.preview.example.com
*.preview.example.combranch.preview.example.compreview.example.com, deep.branch.preview.example.com
preview.example.compreview.example.comany child hostname

To serve both the preview landing page and one-label branch hosts, request both names as certificate identifiers:

preview.example.com
*.preview.example.com

Do not request *.*.example.com as a shortcut. RFC 9525 permits only one wildcard character and only as the entire left-most label. A client must ignore a presented identifier that violates those rules.

If your host pattern is branch.team.preview.example.com, decide which level is dynamic. A certificate for *.preview.example.com will not cover it. You may need *.team.preview.example.com, per-host certificates, or a flatter public naming model.

Wildcard issuance requires DNS-aware automation

Let’s Encrypt documents that HTTP-01 cannot issue wildcard certificates. DNS-01 can, by proving control with a TXT record at _acme-challenge.<name>.

_acme-challenge.preview.example.com.  IN  TXT  "ACME validation token"

Production renewal needs more than a one-time manual TXT edit:

  • use a DNS provider API supported by the ACME client
  • scope credentials to the smallest zone and permissions possible
  • keep full DNS credentials off the public web server when feasible
  • wait for authoritative propagation before asking the CA to validate
  • remove stale challenge TXT values after issuance
  • monitor renewal failure well before certificate expiry

DNS-01 can also be delegated with CNAME or NS records to a validation-specific zone. That can reduce the privileges held by the application environment, but the delegation itself becomes production infrastructure and needs an owner.

If CAA restricts issuers, make sure the wildcard request is authorized correctly. The CAA issue and issuewild guide explains when a separate issuewild rule is—and is not—needed.

The application must fail closed

DNS answers only direct traffic. The router must still distinguish active hosts from random names.

const suffix = ".preview.example.com";
const activePreviews = new Set(["main", "release-2026-07", "pr-482"]);

function routePreview(requestHost) {
  const host = requestHost.toLowerCase().replace(/:\d+$/, "");

  if (!host.endsWith(suffix)) {
    return new Response("Not found", { status: 404 });
  }

  const label = host.slice(0, -suffix.length);

  if (!/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/.test(label)) {
    return new Response("Not found", { status: 404 });
  }

  if (!activePreviews.has(label)) {
    return new Response("Not found", { status: 404 });
  }

  return servePreview(label);
}

This example intentionally accepts one label only. It returns 404 for a never-provisioned host instead of serving a generic page. A known preview that has been explicitly retired can return 410 Gone while cleanup propagates.

Authentication is preferable for private staging. If a preview must be public but should stay out of search, add a crawlable noindex directive; do not block the crawler in robots.txt and expect it to discover that directive.

Illustrative wildcard verification

The image below demonstrates the kinds of positive and negative lookups to record. It is not a terminal capture from a live zone.

Illustrative terminal-style wildcard DNS checks for intended and random example hostnames

Illustrative example using reserved example domains and IPs.

Test the gaps, not just the happy path

Run tests against the authoritative answer, a public resolver, TLS, and the application:

# Intended one-label preview
dig branch-482.preview.example.com CNAME +short
curl -I https://branch-482.preview.example.com

# Random one-label preview: DNS may answer, app must reject it
dig random-9f31.preview.example.com CNAME +short
curl -I https://random-9f31.preview.example.com

# Extra depth: certificate and router should behave as designed
curl -I https://deep.branch-482.preview.example.com

# Explicit hostname outside the wildcard namespace
dig docs.example.com CNAME +short

For each result, record the expected DNS source, certificate identifier, HTTP status, and application owner. A successful dig query is not a successful launch if TLS fails or the application returns a placeholder.

Operate the wildcard as a lifecycle system

Before launch, establish these controls:

  • a source of truth for active labels
  • an explicit owner for the wildcard record and preview router
  • one-label versus multi-label naming rules
  • certificate coverage and automated renewal monitoring
  • authentication or search directives for non-production surfaces
  • 404 behavior for unknown names and 410 behavior for retired names when appropriate
  • deletion triggered by merge, release, tenant removal, or expiry
  • a recurring public subdomain inventory that includes the wildcard controller

A wildcard is successful when it makes approved hostname creation routine while unknown names remain uninteresting. If every arbitrary label produces a public 200, a default site, or a server error, the wildcard has removed a DNS task by creating a larger routing and cleanup problem.

Sources and further reading

Vendor behavior can change. Use these primary sources to confirm the current product-specific details.

Continue learning

  1. 01
    A Records and CNAME Records: Choosing a DNS Target

    Compare direct IPv4 records with hostname aliases, including CNAME coexistence and zone-apex constraints, provider-specific alias features, and verification steps.

    Read
  2. 02
    DNS Propagation: TTLs, Caches, and Verification

    Understand why DNS answers differ after a change, how TTL and negative caching affect what resolvers return, and how to separate authoritative DNS from recursive and application issues.

    Read
  3. 03
    CNAME Flattening Explained

    Understand why the zone apex cannot be an ordinary CNAME, how flattening and provider Alias features synthesize address answers, and how to verify and roll back the real target.

    Read