ACME Issuer
The ACME issuer manages certificates using the ACME protocol (RFC 8555), compatible with Let’s Encrypt, ZeroSSL ACME, and other ACME CAs.Configuration
string
default:"acme"
Module identifier for ACME issuer.
string
default:"https://acme-v02.api.letsencrypt.org/directory"
The URL to the CA’s ACME directory endpoint.Common values:
https://acme-v02.api.letsencrypt.org/directory(Let’s Encrypt production)https://acme-staging-v02.api.letsencrypt.org/directory(Let’s Encrypt staging)https://acme.zerossl.com/v2/DV90(ZeroSSL ACME)
string
The URL to the test CA’s ACME directory endpoint.This endpoint is only used during retries if there is a failure using the primary CA.
string
Your email address, so the CA can contact you if necessary.
Not required, but strongly recommended so you can be reached if there is a problem. Your email is not sent to any Caddy mothership or used for any purpose other than ACME transactions.
string
Optionally select an ACME profile to use for certificate orders.Must be a profile name offered by the ACME server, which are listed at its directory endpoint.
string
If you have an existing account with the ACME server, put the private key here in PEM format.The ACME client will look up your account information with this key first before trying to create a new one. Supports placeholders (e.g., environment variables).
object
If using an ACME CA that requires external account binding, specify the CA-provided credentials here.
duration
default:"0"
Time to wait before timing out an ACME operation.Default of 0 means no timeout.
duration
default:"0"
The validity period to ask the CA to issue a certificate for.Default of 0 means CA chooses lifetime. This value computes the “notAfter” field of the ACME order; the system must have a reasonably synchronized clock.
EXPERIMENTAL: Subject to change.
ACME Challenges
object
Configures the various ACME challenge types.
HTTP Challenge
boolean
default:"false"
If true, the HTTP challenge will be disabled.
integer
An alternate port on which to service the HTTP challenge.
The HTTP challenge port is hard-coded into the ACME spec (port 80) and cannot be changed. You would need to forward packets from port 80 to this alternate port.
TLS-ALPN Challenge
boolean
default:"false"
If true, the TLS-ALPN challenge will be disabled.
integer
An alternate port on which to service the TLS-ALPN challenge.
The TLS-ALPN challenge port is hard-coded into the spec (port 443) and cannot be changed. You would need to forward packets from port 443 to this alternate port.
DNS Challenge
object
Configures the ACME DNS challenge.
This is the only challenge type that does not require a direct connection to Caddy from an external server. It’s typically used when behind firewalls or for wildcard certificates.
object
required
The DNS provider module to use which will manage DNS records relevant to the ACME challenge.Example providers:
cloudflare, route53, gandi, etc.duration
The TTL of the TXT record used for the DNS challenge.
duration
default:"0"
How long to wait before starting propagation checks.
duration
default:"2m"
Maximum time to wait for temporary DNS record to appear.Set to
-1 to disable propagation checks.array
Custom DNS resolvers to prefer over system/built-in defaults.Often necessary when using split-horizon DNS.Example:
["8.8.8.8:53", "1.1.1.1:53"]string
Override the domain to use for the DNS challenge.This delegates the challenge to a different domain (e.g., one that updates faster or has a provider API).
Challenge Distribution
string
Optionally customize the host to which a listener is bound if required for solving a challenge.
boolean
default:"true"
Whether distributed solving is enabled.Set to
Applies to HTTP and TLS-ALPN challenges. When enabled, challenge info is written to storage backend for distribution across a cluster.
false only if you cannot reliably use storage backend for writing/distributing challenge info. When disabled, challenges can only be solved from the Caddy instance that initiated the challenge (with exception for HTTP challenges initiated with the same ACME account).Certificate Chain Preferences
object
Preferences for selecting alternate certificate chains, if offered by the CA.By default, the first offered chain will be selected.
boolean
Prefer chains with the fewest number of bytes.
array
Select first chain having a root with one of these common names.Example:
["ISRG Root X1", "ISRG Root X2"]array
Select first chain that has any issuer with one of these common names.
Advanced Options
array
An array of files of CA certificates to accept when connecting to the ACME CA.
object
Forward proxy module configuration for ACME requests.
ACME Examples
Basic Let’s Encrypt
DNS Challenge with Cloudflare
External Account Binding
Preferred Chain Selection
ZeroSSL Issuer
The ZeroSSL issuer uses the ZeroSSL API directly (distinct from ZeroSSL’s ACME endpoint).To use ZeroSSL’s ACME endpoint, use the ACME issuer configured with ZeroSSL’s ACME directory.
Configuration
string
default:"zerossl"
Module identifier for ZeroSSL issuer.
string
required
The API key (or “access key”) for using the ZeroSSL API.Supports placeholders for environment variables.
integer
How many days the certificate should be valid for.
string
The host to bind to when opening a listener for verifying domain names (or IPs).
integer
If HTTP is forwarded from port 80, specify the forwarded port here.
object
Use CNAME validation instead of HTTP.ZeroSSL’s API uses CNAME records for DNS validation, similar to how Let’s Encrypt uses TXT records for the DNS challenge.Accepts same configuration as ACME DNS challenge (provider, TTL, propagation settings, etc.).
ZeroSSL Example
Internal Issuer
The internal issuer generates certificates using a locally-configured CA (managed by Caddy’s PKI app).Perfect for development, testing, or internal services. Certificates are signed by Caddy’s internal CA.
Configuration
string
default:"internal"
Module identifier for internal issuer.
string
default:"local"
The ID of the CA to use for signing.The CA can be configured with the
pki app.duration
default:"12h"
The validity period of certificates.
boolean
default:"false"
If true, the root will be the issuer instead of the intermediate.
Internal Issuer Example
Development Configuration
Caddyfile Configuration
ACME Issuer
ZeroSSL Issuer
Internal Issuer
Multi-Issuer Redundancy
Caddy can use multiple issuers for redundancy. If the first fails, it tries the next:Best Practices
DNS Challenge: Required for wildcard certificates and useful when Caddy is behind a firewall. Requires a supported DNS provider.
Internal CA: Great for development, but clients will show security warnings unless they trust your CA. Install Caddy’s root certificate on client devices for testing.