lego DNS-01 with the DNScale DNS Provider
Use lego v5+ with DNScale to automate Let's Encrypt DNS-01 certificates, including wildcard certificates, Docker runs, systemd renewals, and external certificate use with Caddy or Traefik.
TL;DR
DNScale is built into lego v5+ as DNS provider `dnscale`. Set `DNSCALE_API_TOKEN`, run lego with `--dns dnscale`, test first against Let's Encrypt staging, then schedule `lego renew` with a deploy hook that reloads your web server or proxy. Traefik and other Go products only support DNScale after they embed lego v5+; Caddy needs a native DNS module for in-process DNS-01, so use lego as an external certificate runner until then.
What you'll learn
- Install or run a lego v5+ binary that includes the DNScale DNS provider
- Issue a Let's Encrypt wildcard certificate through DNScale DNS-01
- Store the DNScale token safely with environment variables or `_FILE` secrets
- Renew certificates unattended and hand them to nginx, Caddy, Traefik, or another TLS terminator
The lego ACME client can now solve DNS-01 challenges through DNScale. That means a single Go binary can create the temporary _acme-challenge TXT record, wait for propagation, complete the ACME validation, and clean the record up after issuance.
Use this guide when you want a lightweight certificate runner for:
- Wildcard certificates such as
*.example.com - Origins behind edge proxies or load balancers
- Hosts without a public HTTP listener on port 80
- Internal services that still need publicly trusted TLS certificates
- External certificate management for proxies such as nginx, Caddy, HAProxy, or Traefik
For the broader ACME comparison across certbot, acme.sh, cert-manager, and lego, see Let's Encrypt DNS-01 Challenges with DNScale.
How the integration works
lego loads DNS providers at build time. In lego v5+, the DNScale provider is compiled into the official binary under provider code dnscale.
At issuance time, lego:
- Reads
DNSCALE_API_TOKENorDNSCALE_API_TOKEN_FILE. - Finds the matching DNScale zone for the requested name.
- Creates a TXT record at
_acme-challenge.<name>. - Polls DNS until the TXT value is visible.
- Asks the ACME CA to validate the challenge.
- Deletes the TXT record.
- Writes the certificate and private key under the lego storage path.
This is why the token should be scoped tightly. The ACME runner needs read access to zones and create/delete access for challenge TXT records; it does not need billing, user-management, or unrelated zone access.
Prerequisites
Before starting, prepare:
- A DNScale-hosted zone, for example
example.com - A DNScale API token scoped to that zone
- lego v5 or newer
- A contact email address for the ACME account
- CAA records that allow your CA, if you publish CAA
Check your lego version:
lego --versionIf you install from Go source, use the v5 module path:
go install github.com/go-acme/lego/v5/cmd/lego@v5.2.0You can also use the official container image in the Docker example below.
First staging issuance
Always test a new ACME setup against Let's Encrypt staging before production. Staging certificates are not trusted by browsers, but they prove that token permissions, zone discovery, propagation, and cleanup all work without spending production rate limits.
export DNSCALE_API_TOKEN="<your-token>"
lego \
--server https://acme-staging-v02.api.letsencrypt.org/directory \
--accept-tos \
--email admin@example.com \
--dns dnscale \
--path /var/lib/lego \
--domains example.com \
--domains "*.example.com" \
runAfter the run succeeds, inspect the output directory:
sudo ls -l /var/lib/lego/certificates/For a request whose first domain is example.com, lego writes files similar to:
example.com.crt
example.com.issuer.crt
example.com.json
example.com.keyProduction issuance
Run the same command without the staging server:
DNSCALE_API_TOKEN="<your-token>" lego \
--accept-tos \
--email admin@example.com \
--dns dnscale \
--path /var/lib/lego \
--domains example.com \
--domains "*.example.com" \
runIf your environment has slower DNS visibility, tune the DNScale propagation settings:
DNSCALE_API_TOKEN="<your-token>" \
DNSCALE_PROPAGATION_TIMEOUT=120 \
DNSCALE_POLLING_INTERVAL=5 \
DNSCALE_TTL=120 \
lego \
--accept-tos \
--email admin@example.com \
--dns dnscale \
--path /var/lib/lego \
--domains example.com \
--domains "*.example.com" \
runStore the token as a file
For servers and containers, prefer a secret file over a literal environment variable in shell history:
sudo install -d -m 700 /etc/lego
printf '%s' '<your-token>' | sudo tee /etc/lego/dnscale-token >/dev/null
sudo chmod 600 /etc/lego/dnscale-tokenThen run lego with _FILE:
DNSCALE_API_TOKEN_FILE=/etc/lego/dnscale-token lego \
--accept-tos \
--email admin@example.com \
--dns dnscale \
--path /var/lib/lego \
--domains example.com \
--domains "*.example.com" \
runDocker example
This command keeps lego state in a local .lego directory and passes the DNScale token through the container environment:
mkdir -p .lego
docker run --rm \
-e DNSCALE_API_TOKEN="<your-token>" \
-v "$PWD/.lego:/root/.lego" \
goacme/lego:v5.2.0 \
--accept-tos \
--email admin@example.com \
--dns dnscale \
--domains example.com \
--domains "*.example.com" \
runFor production containers, mount the token from your secret manager and use DNSCALE_API_TOKEN_FILE:
docker run --rm \
-e DNSCALE_API_TOKEN_FILE=/run/secrets/dnscale_api_token \
-v "$PWD/.lego:/root/.lego" \
-v /run/secrets/dnscale_api_token:/run/secrets/dnscale_api_token:ro \
goacme/lego:v5.2.0 \
--accept-tos \
--email admin@example.com \
--dns dnscale \
--domains example.com \
--domains "*.example.com" \
runAutomatic renewals with systemd
Create a renewal script:
sudo tee /usr/local/sbin/renew-example-com >/dev/null <<'EOF'
#!/bin/sh
set -eu
export DNSCALE_API_TOKEN_FILE=/etc/lego/dnscale-token
lego \
--accept-tos \
--email admin@example.com \
--dns dnscale \
--path /var/lib/lego \
--domains example.com \
--domains "*.example.com" \
--renew-days 30 \
--deploy-hook "systemctl reload nginx" \
renew
EOF
sudo chmod 750 /usr/local/sbin/renew-example-comThen add a service and timer:
# /etc/systemd/system/lego-example-com.service
[Unit]
Description=Renew example.com certificate with lego and DNScale
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/renew-example-com# /etc/systemd/system/lego-example-com.timer
[Unit]
Description=Daily lego renewal check for example.com
[Timer]
OnCalendar=daily
RandomizedDelaySec=1h
Persistent=true
[Install]
WantedBy=timers.targetEnable the timer:
sudo systemctl daemon-reload
sudo systemctl enable --now lego-example-com.timer
sudo systemctl start lego-example-com.servicelego renews only when the certificate is inside the renewal window. Running the timer daily is normal.
Use with Caddy or Traefik as external certs
lego can manage the certificate while another Go-based product serves it. This is the safe compatibility path when the proxy does not yet expose DNScale as an in-process DNS provider.
Caddy with certificate files
Point Caddy at the files created by lego:
example.com, *.example.com {
tls /var/lib/lego/certificates/example.com.crt /var/lib/lego/certificates/example.com.key
reverse_proxy 127.0.0.1:8080
}Reload Caddy from the lego deploy hook:
--deploy-hook "systemctl reload caddy"Do not use tls { dns dnscale ... } unless your Caddy build includes a native DNScale DNS module. Caddy DNS modules are separate from lego DNS providers.
Traefik with certificate files
With Traefik's file provider, publish the lego-managed files in dynamic configuration:
tls:
certificates:
- certFile: /certs/example.com.crt
keyFile: /certs/example.com.keyMount /var/lib/lego/certificates into the Traefik container or host path that backs /certs, then reload Traefik after successful renewal if your deployment does not watch the file provider automatically.
Traefik's native ACME dnsChallenge.provider: dnscale will work only in Traefik versions that embed lego v5 or newer. Older Traefik builds embed lego v4 and will reject dnscale as an unknown DNS provider.
Environment variable reference
| Variable | Required | Purpose |
|---|---|---|
DNSCALE_API_TOKEN | Yes, unless _FILE is used | DNScale API token. |
DNSCALE_API_TOKEN_FILE | Alternative | Path to a file containing the DNScale token. |
DNSCALE_TTL | No | TTL for challenge TXT records, in seconds. |
DNSCALE_PROPAGATION_TIMEOUT | No | Maximum time lego waits for TXT propagation, in seconds. |
DNSCALE_POLLING_INTERVAL | No | Time between propagation checks, in seconds. |
DNSCALE_HTTP_TIMEOUT | No | Timeout for DNScale API requests, in seconds. |
Troubleshooting
unrecognized DNS provider: dnscale
The binary is not lego v5+. Upgrade the standalone lego CLI, use the official v5 container image, or wait for the embedding product to ship a lego v5+ dependency.
some credentials information are missing: DNSCALE_API_TOKEN
Set DNSCALE_API_TOKEN, or set DNSCALE_API_TOKEN_FILE to a readable file. The file must contain the raw token, not DNSCALE_API_TOKEN=<token>.
zone not found
Check that the requested domain is hosted in DNScale and that the token can read that zone. For www.example.com, lego searches upward for example.com; if that zone is not visible to the token, challenge setup fails.
Validation times out
Increase DNSCALE_PROPAGATION_TIMEOUT to 120 or 180 seconds and keep DNSCALE_TTL low, usually 120 seconds. Also check for stale negative DNS cache from a previous failed attempt.
CAA blocks issuance
If you publish CAA records, allow your ACME CA:
example.com. 3600 CAA 0 issue "letsencrypt.org"
example.com. 3600 CAA 0 issuewild "letsencrypt.org"Confirm with:
dig CAA example.com +shortRelated guides
Frequently asked questions
- Which lego version do I need for DNScale?
- DNScale support starts with lego v5.0.0. Use lego v5 or newer and verify with `lego --version`. If a product embeds lego internally, that product must also ship a lego v5+ dependency before provider `dnscale` is available there.
- What environment variable does lego use for DNScale?
- Set `DNSCALE_API_TOKEN` to a DNScale API token, or set `DNSCALE_API_TOKEN_FILE` to a path containing only the token value. Optional tuning variables are `DNSCALE_TTL`, `DNSCALE_PROPAGATION_TIMEOUT`, `DNSCALE_POLLING_INTERVAL`, and `DNSCALE_HTTP_TIMEOUT`.
- Can I use this for wildcard certificates?
- Yes. DNS-01 is the ACME challenge type required for wildcard certificates. Request both the apex and wildcard names, for example `--domains example.com --domains "*.example.com"`, so one certificate covers both.
- Can I use DNScale directly in Traefik today?
- Only if your Traefik build embeds lego v5 or newer. Builds that still vendor lego v4 do not know provider `dnscale`. Until your Traefik version includes lego v5+, run lego externally and point Traefik at the resulting certificate files.
- Can I configure `dns dnscale` in Caddy?
- Not as a plain lego provider. Caddy uses CertMagic and Caddy DNS modules, not lego's provider list. Use lego externally and configure Caddy with certificate files until a native DNScale Caddy DNS module exists.
Related guides
Ready to manage your DNS with confidence?
DNScale provides anycast DNS hosting with a global network, real-time analytics, and an easy-to-use API.
Start free