Last updated: 2026-02-11
Caddy TLS/SSL Configuration Guide
This guide covers TLS/SSL settings for Caddy, a modern web server that provides automatic HTTPS out of the box. Caddy automatically obtains and renews certificates from Let's Encrypt, configures strong TLS defaults, and enables HSTS -- making it one of the most secure web servers by default.
Prerequisites
- Caddy 2.0 or later
- A publicly accessible domain name (for automatic certificate issuance)
Automatic HTTPS (Default Behavior)
Caddy's defining feature is automatic HTTPS. With a minimal Caddyfile, Caddy will:
- Obtain a TLS certificate from Let's Encrypt (or ZeroSSL)
- Automatically renew the certificate before it expires
- Redirect HTTP to HTTPS
- Enable HSTS
- Use strong TLS 1.2 and TLS 1.3 defaults
A basic Caddyfile with automatic TLS:
example.com {
root * /var/www/html
file_server
}
That's it. No TLS configuration is needed for most deployments. Caddy's defaults are already strong and secure.
Default TLS Settings
Out of the box, Caddy configures:
- Protocols: TLS 1.2 and TLS 1.3
- TLS 1.3 cipher suites: TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384, TLS_CHACHA20_POLY1305_SHA256
- TLS 1.2 cipher suites: ECDHE+AESGCM, ECDHE+CHACHA20 (only forward-secret AEAD ciphers)
- ECDH curves: X25519, P-256, P-384
- HSTS: Enabled automatically
Custom TLS Configuration
If you need to customize TLS settings (for compliance, auditing, or specific client requirements), use the tls directive in your Caddyfile.
Protocol Versions
Restrict to specific TLS versions:
example.com {
tls {
protocols tls1.2 tls1.3
}
root * /var/www/html
file_server
}
Cipher Suites
Caddy uses Go's crypto/tls cipher names (IANA format). To explicitly set cipher suites:
example.com {
tls {
ciphers TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
}
}
TLS 1.3 cipher suites cannot be customized in Go's TLS stack. All three TLS 1.3 ciphers are always enabled, which is fine since they are all strong.
ECDH Curves
Specify the elliptic curves for key exchange:
example.com {
tls {
curves x25519 secp256r1 secp384r1
}
}
Using Your Own Certificates
To use externally obtained certificates instead of automatic issuance:
example.com {
tls /etc/caddy/ssl/fullchain.pem /etc/caddy/ssl/privkey.pem
}
Internal (Self-Signed) Certificates
For internal services that don't need publicly trusted certificates:
internal.example.com {
tls internal
}
Caddy will generate a locally-trusted certificate using its built-in CA.
HSTS
Caddy enables HSTS automatically for public-facing sites. To customize the HSTS header:
example.com {
header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
}
On-Demand TLS
For environments with many domains, Caddy supports on-demand TLS -- certificates are obtained at the time of the first TLS handshake:
{
on_demand_tls {
ask http://localhost:5555/check
}
}
https:// {
tls {
on_demand
}
}
The ask endpoint should verify that the requested domain is authorized before Caddy obtains a certificate for it.
Complete Custom Configuration Example
{
# Global options
email admin@example.com
}
example.com {
tls {
protocols tls1.2 tls1.3
ciphers TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
curves x25519 secp256r1 secp384r1
}
header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
root * /var/www/html
file_server
}
Verification
Validate and reload the Caddy configuration:
caddy validate --config /etc/caddy/Caddyfile
caddy reload --config /etc/caddy/Caddyfile
Test the TLS connection:
openssl s_client -connect example.com:443 -tls1_2
openssl s_client -connect example.com:443 -tls1_3
Check Caddy's certificate management status:
caddy trust
Test your configuration externally using Qualys SSL Labs at https://www.ssllabs.com/ssltest/.