ACME challenges: DNS-01 and HTTP-01
Choose an issuance path
ACME challenges prove that you control a domain before a certificate authority issues its certificate.
- DNS-01 through the TokenTimer agent: the agent publishes a
_acme-challengeTXT record through an allowlisted DNS provider. Use this for agent-managed issuance and renewal, wildcard certificates, or hosts that cannot accept public HTTP traffic. Start with DNS-01 providers, then the Cloudflare worked example. - HTTP-01 through your own ACME client: a public web server serves a challenge file under
/.well-known/acme-challenge/. Use this when you already manage certificates with a webroot-capable client. The example below runs Certbot independently; TokenTimer can monitor the deployed certificate afterwards.
The bundled agent's Certbot and acme.sh adapters currently execute DNS-01 only, including on Windows/IIS targets. There is no agent challengeType: "http-01" or webroot setting. Adding --webroot to an agent command profile does not change that adapter into an HTTP-01 workflow.
For Kubernetes certificates already issued by cert-manager, keep challenge configuration in its Issuer or ClusterIssuer and use CertOps with ACME and cert-manager for observation and reporting. The bundled host agent's DNS-01 restriction does not change your external ACME client's challenge configuration.
HTTP-01 prerequisites
For Let's Encrypt HTTP-01, every requested hostname must resolve to the web server and be reachable on port 80. The challenge path must serve the expected file without login or an application rewrite. HTTP-01 cannot issue wildcard certificates; use DNS-01 for those. See Let's Encrypt challenge types.
For the webroot example, you need Certbot installed on a Linux host, permission to write the webroot, and a running web server that serves /var/www/example for www.example.com. Replace the domain, email, and directory with your own values.
Example: HTTP-01 with Certbot webroot
Run this on the web server, independently of the TokenTimer agent. It requests a staging certificate without changing your web-server TLS configuration:
sudo certbot certonly \
--webroot -w /var/www/example \
-d www.example.com \
--cert-name www.example.com-staging \
--server https://acme-staging-v02.api.letsencrypt.org/directory \
--non-interactive --agree-tos --email ops@example.com
Check that Certbot reports success, then inspect the result:
sudo openssl x509 \
-in /etc/letsencrypt/live/www.example.com-staging/cert.pem \
-noout -subject -issuer -dates
A staging certificate is not browser-trusted. For production, run the same request with --cert-name www.example.com and --server https://acme-v02.api.letsencrypt.org/directory. Configure your web server to use the resulting fullchain.pem and local privkey.pem, then reload it using your normal deployment procedure. Keep private keys on the host.
Certbot owns renewal for this workflow. Verify its timer or scheduled task and the deployment hook that reloads your server after renewal. See Certbot's webroot and renewal guide. TokenTimer's renewal scheduler does not take over because the certificate is being monitored.
Track the deployed certificate in TokenTimer
After deploying a production certificate, add its HTTPS URL in Endpoint & SSL monitoring. Confirm that the certificate expiry shown in TokenTimer matches the certificate your server presents, and assign contact groups for expiry reminders.
An endpoint observation supplies certificate metadata; it does not grant the agent access to the private key. Such certificates are monitored rather than automatically renewed by TokenTimer. See Which certificates are renewable.
If your external tooling also needs to report job progress, use the Executor API with an existing job and a scoped machine token. Reporting events is separate from issuing, installing, and verifying the certificate.
Troubleshooting HTTP-01
- Challenge returns 404: check the hostname's document root and whether your server serves files below
/.well-known/acme-challenge/. - Connection timeout: check public DNS and inbound port 80, including the firewall and load balancer. Every server answering for the hostname must be able to serve the challenge.
- Challenge hits a login or application page: exclude the challenge path from authentication and catch-all rewrites.
- Wildcard requested: switch to DNS-01; changing the HTTP webroot cannot validate a wildcard.
- Issuance succeeded but TokenTimer shows an old expiry: confirm your server loaded the new production certificate, then refresh its endpoint monitor. A file on disk alone does not prove it is served.