# Understanding the Limitations of Wildcard Certificates in mkcert

> Discover the limitations of wildcard certificates in mkcert. Learn about single-level DNS labels, second-level patterns, and filename sanitization for filesystem compatibility.

- Repository: [Filippo Valsorda/mkcert](https://github.com/FiloSottile/mkcert)
- Tags: best-practices
- Published: 2026-03-05

---

**Wildcard certificates in mkcert are limited to single-level DNS labels and trigger warnings for second-level patterns, while asterisks in filenames are automatically sanitized to `_wildcard` to ensure filesystem compatibility.**

Wildcard certificates in mkcert provide convenient TLS coverage for subdomains, but they inherit strict constraints from the X.509 standard. When using FiloSottile/mkcert to generate local development certificates, understanding these limitations prevents subdomain mismatch errors and browser compatibility issues.

## How Wildcard Certificates Work in mkcert

mkcert generates X.509-compliant certificates that follow standard wildcard semantics. The tool validates hostnames and issues warnings based on the `printHosts` function in [`cert.go`](https://github.com/FiloSottile/mkcert/blob/main/cert.go), ensuring users understand the constraints before deploying certificates to local trust stores.

## Key Limitations of Wildcard Certificates in mkcert

### One-Level Depth Restriction

The X.509 standard permits wildcards to match **exactly one DNS label**. In [`cert.go`](https://github.com/FiloSottile/mkcert/blob/main/cert.go) (lines 58-62), mkcert explicitly reminds users that `*.example.com` matches `foo.example.com` but **does not** match `a.b.example.com`:

> "Reminder: X.509 wildcards only go one level deep, so this won't match a.b.*"

This restriction is fundamental to the certificate structure and cannot be bypassed through mkcert configuration.

### Second-Level Wildcard Compatibility Issues

While mkcert accepts second-level wildcard patterns such as `*.*.example.com` or `*.12345` via the CLI, most browsers reject these certificates as invalid. The `printHosts` function in [`cert.go`](https://github.com/FiloSottile/mkcert/blob/main/cert.go) (lines 52-55) detects these patterns and issues a warning:

> "Warning: many browsers don't support second-level wildcards like `*.*.example.com`"

Generating these certificates may result in TLS handshake failures in Chrome, Firefox, and Safari despite the certificate being technically valid according to X.509 specifications.

### Filename Sanitization Constraints

Because asterisks (`*`) are invalid characters in most filesystems, mkcert sanitizes output filenames by replacing `*` with `_wildcard`. The `fileNames` function in [`cert.go`](https://github.com/FiloSottile/mkcert/blob/main/cert.go) (lines 76-80) implements this transformation:

```go
defaultName = strings.Replace(defaultName, "*", "_wildcard", -1)

```

This substitution affects only the output filename (e.g., `_wildcard.example.com+1.pem`) and does not alter the certificate's Subject Alternative Name (SAN) entries. Users must reference the sanitized filenames when configuring web servers.

## Practical Examples and Warnings

### Generating a Standard One-Level Wildcard

```bash
mkcert "*.example.com"

```

Output:

```

Created a new certificate valid for the following names 📜
 - "*.example.com"
The certificate is at "./_wildcard.example.com+1.pem" ✅

```

### Attempting a Second-Level Wildcard (Triggers Warning)

```bash
mkcert "*.*.example.com"

```

Output:

```

Created a new certificate valid for the following names 📜
 - "*.*.example.com"
  Warning: many browsers don't support second-level wildcards like "*.*.example.com" ⚠️
Reminder: X.509 wildcards only go one level deep, so this won't match a.b.* ℹ️

```

### Using the Certificate in a Node.js Server

```javascript
const https = require('https');
const fs = require('fs');

https.createServer({
  key: fs.readFileSync('_wildcard.example.com-key.pem'),
  cert: fs.readFileSync('_wildcard.example.com+1.pem')
}, (req, res) => {
  res.writeHead(200);
  res.end('Hello Secure World\n');
}).listen(443);

```

## Summary

- **Single-level restriction**: Wildcards in mkcert match only one DNS label (e.g., `*.example.com` covers `foo.example.com` but not `a.b.example.com`), as enforced by X.509 standards and reminded in [`cert.go`](https://github.com/FiloSottile/mkcert/blob/main/cert.go).
- **Browser compatibility warnings**: Second-level wildcards like `*.*.example.com` generate certificates that most browsers reject, triggering explicit warnings from the `printHosts` function.
- **Filename sanitization**: Asterisks are converted to `_wildcard` in output filenames via the `fileNames` function in [`cert.go`](https://github.com/FiloSottile/mkcert/blob/main/cert.go) to ensure cross-platform filesystem compatibility without affecting certificate SAN entries.

## Frequently Asked Questions

### Can mkcert generate wildcards that match multiple subdomain levels?

No. mkcert follows the X.509 standard, which restricts wildcards to exactly one DNS label. A certificate for `*.example.com` will match `foo.example.com` but will not match `a.b.example.com`. The tool explicitly prints a reminder about this limitation when generating wildcard certificates.

### Why does mkcert rename my wildcard certificate files to use "_wildcard"?

Filesystems do not allow asterisks (`*`) in filenames. The `fileNames` function in [`cert.go`](https://github.com/FiloSottile/mkcert/blob/main/cert.go) sanitizes the default output name by replacing `*` with `_wildcard` using `strings.Replace`. This affects only the filename (e.g., `_wildcard.example.com+1.pem`) and does not modify the certificate's internal DNS names.

### Are second-level wildcards like *.*.example.com valid in mkcert?

While mkcert will generate a certificate for `*.*.example.com` and the CLI accepts the pattern, the resulting certificate is not widely supported. The `printHosts` function in [`cert.go`](https://github.com/FiloSottile/mkcert/blob/main/cert.go) issues a warning that many browsers reject second-level wildcards. These certificates may cause TLS handshake failures in Chrome, Firefox, and Safari.

### Does mkcert support wildcard certificates for IP addresses?

No. Wildcard patterns such as `*.192.168.1.1` are not valid because wildcards apply only to DNS names (domain labels), not to IP addresses. mkcert validates hostnames according to X.509 rules and will not generate certificates with wildcard patterns for IP addresses.