# Wildcard certificates

A wildcard certificate carries a name of the form `*.example.com` and is valid for every hostname one label below that domain — `api.example.com` and `www.example.com` match, while `a.b.example.com` does not, because the asterisk replaces exactly one label and never two. The bare domain `example.com` does not match its own wildcard either, which is why wildcard certificates almost always list both `*.example.com` and `example.com` in the Subject Alternative Name extension. The asterisk must be the entire leftmost label, so partial forms such as `www*.example.com` are neither issued by public CAs nor accepted by clients, and no CA may issue a wildcard at or above a public suffix such as `*.co.uk`. Obtaining one over ACME requires the DNS-01 challenge, because HTTP-01 cannot prove control of names that do not exist yet.

Source: https://certguru.io/concepts/wildcard-certificate/
Last updated: 2026-08-19
Commands verified against OpenSSL 3.5.7.

---

## What a wildcard actually matches

The asterisk stands in for **one DNS label**, and it must be the whole of the leftmost label. That
single rule explains every surprise on this page:

| Certificate name | Hostname | Match? |
| --- | --- | --- |
| `*.example.com` | `www.example.com` | Yes |
| `*.example.com` | `api.example.com` | Yes |
| `*.example.com` | `example.com` | **No** — there is no label to replace |
| `*.example.com` | `a.b.example.com` | **No** — that is two labels |
| `*.b.example.com` | `a.b.example.com` | Yes |
| `www*.example.com` | `www1.example.com` | **No** — partial labels are not issued or accepted |
| `*.*.example.com` | `a.b.example.com` | **No** — one wildcard only |
| `*.co.uk` | anything | Not issuable — public suffix |

> **The bare domain is the one people forget**
>
> `https://example.com/` fails against a certificate that lists only `*.example.com`, with
>   [NET::ERR_CERT_COMMON_NAME_INVALID](/errors/err-cert-common-name-invalid/) in Chrome. The
>   certificate is perfectly valid; it simply does not name the host. Always request the apex
>   alongside the wildcard.

## Inspecting a wildcard certificate

The names live in the Subject Alternative Name extension, not the Common Name — clients have
ignored the CN since RFC 6125. A correctly requested wildcard lists both entries:

*What names does this request cover?*

```bash
openssl req -in wildcard.csr -noout -text | grep -A1 "Subject Alternative Name"
```

Expected output:

```
X509v3 Subject Alternative Name:
    DNS:*.example.com, DNS:example.com
```

For a certificate rather than a request:

*Read the SAN list off a live server*

```bash
openssl s_client -connect www.example.com:443 -servername www.example.com /dev/null \
  | openssl x509 -noout -ext subjectAltName
```

## Requesting one

Generate the CSR with both names in the SAN extension. The Common Name is cosmetic here, but
conventionally carries the wildcard:

*A wildcard CSR covering the apex too*

```bash
openssl req -new -newkey rsa:2048 -nodes \
  -keyout star-example.key -out star-example.csr \
  -subj "/CN=*.example.com" \
  -addext "subjectAltName=DNS:*.example.com,DNS:example.com"
```

Confirm both names survived before sending it to the CA:

```bash
openssl req -in star-example.csr -noout -text | grep -A1 "Subject Alternative Name"
```

Covering a second level means naming it explicitly — there is no way to express "everything below
this point" in one entry:

*Two levels needs two wildcards*

```bash
openssl req -new -newkey rsa:2048 -nodes \
  -keyout multi.key -out multi.csr \
  -subj "/CN=*.example.com" \
  -addext "subjectAltName=DNS:*.example.com,DNS:example.com,DNS:*.internal.example.com"
```

## Why ACME needs DNS-01

The HTTP-01 challenge proves control of a hostname by serving a file from it. That cannot work for
a wildcard, because the CA would have to pick which of the infinitely many matching hostnames to
test, and most of them do not exist.

DNS-01 proves control of the **zone** instead, by asking you to publish a `TXT` record at
`_acme-challenge.example.com`. Control of the zone implies control of every name under it, which is
exactly the claim a wildcard makes. Every public CA therefore requires DNS-01 for wildcards, and
your ACME client needs API credentials for the DNS provider to automate it. The renewal mechanics
are on [Certbot renewal](/platforms/certbot/).

## Wildcard or multi-SAN?

A wildcard is not automatically the better option. A SAN certificate naming each host explicitly is
often the safer choice:

| | Wildcard | Multi-SAN |
| --- | --- | --- |
| New subdomain | Works immediately, no reissue | Needs a reissue |
| Names visible in Certificate Transparency | Only the wildcard | Every hostname, publicly |
| Key compromise on one host | Exposes a key valid for **all** subdomains | Exposes that certificate only |
| Different teams or machines per subdomain | Everyone needs the same key | Each gets its own |
| Issuance | DNS-01 only | HTTP-01 is fine |

> **The Certificate Transparency angle cuts both ways**
>
> Every publicly trusted certificate is logged, so a multi-SAN certificate publishes your internal
>   hostnames — `staging`, `jenkins`, `admin` — to a searchable public log. A wildcard reveals only
>   that the domain exists. Where hostname disclosure matters, that is a genuine argument for the
>   wildcard, weighed against the shared-key risk.

## Testing locally

A self-signed wildcard is enough to check that a server and its clients handle the matching
correctly before spending a real issuance on it:

*A throwaway wildcard certificate*

```bash
openssl req -x509 -newkey rsa:2048 -nodes -days 30 \
  -keyout star-test.key -out star-test.crt \
  -subj "/CN=*.test.local" \
  -addext "subjectAltName=DNS:*.test.local,DNS:test.local"
```

*Confirm what it covers*

```bash
openssl x509 -in star-test.crt -noout -subject -ext subjectAltName
```


## Frequently asked questions

### Does *.example.com cover example.com?

No. The wildcard replaces a label that must be present, so the bare domain does not match. This surprises people constantly, and the fix is to list `example.com` in the SAN extension alongside the wildcard — which is what CAs do by default when you request both.

### Does *.example.com cover a.b.example.com?

No. One asterisk replaces exactly one label. Covering two levels needs a second wildcard, `*.b.example.com`, listed as an additional SAN entry.

### Can I get a free wildcard certificate?

Yes. Let's Encrypt, ZeroSSL and Google Trust Services all issue wildcards at no cost, but only through the DNS-01 challenge — your ACME client needs API credentials for the DNS provider. HTTP-01 cannot issue a wildcard from any CA.

### Is a wildcard less secure than separate certificates?

It concentrates risk. One private key serves every subdomain, so a compromise on the least important host exposes a key that is also valid for the most important one. Where subdomains sit on different machines or have different owners, separate certificates limit the blast radius.

### Why was my request for *.co.uk or *.com refused?

The CA/Browser Forum forbids issuing a wildcard at or above a public suffix, because it would be valid for every domain under that suffix. Every publicly trusted CA enforces this.


## References

- [RFC 6125 section 6.4.3: wildcard matching](https://www.rfc-editor.org/rfc/rfc6125#section-6.4.3) — the one-label rule and the leftmost-label requirement
- [CA/Browser Forum Baseline Requirements](https://cabforum.org/working-groups/server/baseline-requirements/documents/) — what a public CA may put in a wildcard, and the public-suffix prohibition
- [Let's Encrypt: challenge types](https://letsencrypt.org/docs/challenge-types/) — why DNS-01 is required for wildcard issuance

## Related pages

- https://certguru.io/concepts/san/
- https://certguru.io/openssl/generate-csr-with-san/
- https://certguru.io/errors/err-cert-common-name-invalid/
- https://certguru.io/concepts/free-tls-certificate/
- https://certguru.io/formats/csr/
- https://certguru.io/openssl/generate-csr/

--
CertGuru — https://certguru.io
