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.
- Written by
- 1990Company Editorial Desk
- 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:
- Wildcard DNS decides whether a query receives an answer.
- Application routing decides whether that Host header maps to a real project.
- 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 identifier | Matches | Does not match |
|---|---|---|
*.example.com | app.example.com | example.com, branch.preview.example.com |
*.preview.example.com | branch.preview.example.com | preview.example.com, deep.branch.preview.example.com |
preview.example.com | preview.example.com | any 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 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
404behavior for unknown names and410behavior 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.