Learning Caddy - Wildcard Certificates & DNS Challenge
Episode 9 of 31

Learning Caddy - Wildcard Certificates & DNS Challenge

This episode covers wildcard certificates and the DNS-01 challenge: wildcard syntax, the DNS-01 requirement for wildcards, DNS provider credentials like Cloudflare and Route53, custom builds with xcaddy, and per-site and global configuration.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Introduction

Sometimes you need a single certificate protecting all of your subdomains: app.example.com, api.example.com, blog.example.com, and so on. That's where a wildcard certificate comes in. Unfortunately, wildcards can only be obtained through the DNS-01 challenge — because verification must go through a DNS TXT record, not HTTP.

Episode 9 covers how Caddy manages wildcard certificates. You'll learn wildcard syntax in the Caddyfile, why DNS-01 is the only way, how to configure DNS providers like Cloudflare and Route53, and how to build a custom Caddy binary with xcaddy to add DNS provider modules.

This is also the first episode involving plugins — a concept that becomes a major theme in episode 29. Prepare your DNS provider's API credentials if you want to practice hands-on.

Wildcard Certificates

Syntax and Use Cases

A wildcard certificate covers all subdomains at one level:

Caddyfile with a wildcard
*.example.com {
    root * /var/www/sites/{host}
    file_server
}

The *.example.com block serves app.example.com, api.example.com, and others. Caddy will issue a certificate for *.example.com — a single certificate valid for all those subdomains.

Wildcard Limitations

Important to understand:

  • A wildcard only covers one level. *.example.com does not cover a.b.example.com.
  • Wildcard certificates can't be obtained via HTTP-01; DNS-01 is required.
  • The root domain example.com itself needs an additional certificate.

A common combination: create two certificates — one for the root example.com and one for *.example.com.

Why DNS-01 Is Required

Verification Through a TXT Record

The HTTP-01 challenge needs port 80 publicly accessible for each subdomain — impractical for dozens of subdomains. DNS-01 solves it differently:

  1. The CA gives you a token.
  2. You create a DNS TXT record _acme-challenge.example.com containing the token.
  3. The CA verifies that record.
  4. The certificate is issued.

Because verification goes through DNS, it doesn't matter how many subdomains there are — a single record is enough for a wildcard.

Caddy Handles It Automatically

With the DNS provider module installed, Caddy creates and deletes TXT records automatically using your API credentials. You never touch the DNS panel manually.

Configuring a DNS Provider

Credentials and Environment Variables

DNS provider modules read credentials from environment variables. Example for Cloudflare:

Set Cloudflare credentials
export CF_API_TOKEN=your_token
export CF_ZONE=example.com
caddy run --config Caddyfile

Each provider has its own variables — check the module's documentation. Never write tokens in the Caddyfile; always use environment variables.

Global DNS Provider

Set a global provider so all sites use it:

Global DNS provider
{
    acme_dns cloudflare {env.CF_API_TOKEN}
}
 
*.example.com {
    root * /var/www
    file_server
}

acme_dns cloudflare ... uses Cloudflare for all DNS challenges across every site.

Per Site and Fallback

Combine per-site providers and fallbacks:

Provider per site
a.example.com {
    tls {
        dns cloudflare {env.CF_API_TOKEN}
    }
}
 
b.example.com {
    tls {
        dns digitalocean {env.DO_API_TOKEN}
    }
}

Site A uses Cloudflare, site B uses DigitalOcean. Each provider requires a Caddy binary built with its corresponding module.

Custom Builds with xcaddy

Installing xcaddy

DNS provider modules aren't in the standard binary. To add them, use xcaddy:

Install xcaddy
go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest
xcaddy build --with github.com/caddy-dns/cloudflare

xcaddy build --with ... creates a new Caddy binary that includes the Cloudflare DNS module.

Building with Many Modules

Modules can be combined in a single build:

Build with several modules
xcaddy build \
  --with github.com/caddy-dns/cloudflare \
  --with github.com/caddy-dns/digitalocean \
  --with github.com/mholt/caddy-l4

The result is a custom binary with all those modules. Store this binary on your server and use it in place of the standard caddy. Always track module versions when updating the binary — plugins must be compatible with your Caddy version.

Fallback Strategy and Best Practices

Multiple Providers and Propagation

  • If you have several providers, combine them in the build and configure per site.
  • DNS propagation takes time; some providers need resolver or timeout configuration.
  • Caddy handles retries and waits for propagation automatically.

Credential Security

  • DNS tokens have high power — they can change a domain's DNS.
  • Restrict token permissions to only the _acme-challenge record.
  • Rotate tokens periodically and store them securely in a secret manager.

Conclusion

Episode 9 opened the door to wildcard certificates: *.example.com syntax in the Caddyfile, the DNS-01 challenge requirement for wildcards, DNS provider credentials like Cloudflare and Route53 via environment variables, global and per-site configuration, and custom builds with xcaddy.

Key takeaways:

  • Wildcard certificates can only be obtained via DNS-01, not HTTP-01.
  • acme_dns cloudflare {env.CF_API_TOKEN} sets a global provider.
  • Credentials always go through environment variables, not the Caddyfile.
  • DNS provider modules are added with xcaddy build --with.
  • A wildcard only covers one level; the root domain needs a separate cert.
  • Restrict DNS token permissions to only the ACME challenge.

In the next episode, episode 10, we'll cover custom certificates and internal CA — manual certificates and PEM chains, private CAs with self-signed certs, client certificates for mTLS, Step CA and internal ACME server integration, and on-demand TLS for multi-tenancy. Advanced certificate control awaits.

Learning Caddy - Wildcard Certificates & DNS Challenge | Learning Caddy