caddyserver/caddy · error
certificate lifetime (%s) should be less than intermediate c
Error message
certificate lifetime (%s) should be less than intermediate certificate lifetime (%s)
What it means
Enforced by the internal ACME server (smallstep ACME CA) at provisioning: a certificate authority's leaf `lifetime` must be strictly shorter than the intermediate certificate's lifetime. It only applies when Caddy manages the intermediate itself (ca.Intermediate == nil, i.e. no external intermediate cert was configured); with an externally supplied intermediate the check is skipped. Default intermediate lifetime is 7 days (defaultIntermediateLifetime = 24h*7 in ca.go).
Source
Thrown at modules/caddypki/acmeserver/acmeserver.go:160
}
ash.warnIfPolicyAllowsAll()
// get a reference to the configured CA
appModule, err := ctx.App("pki")
if err != nil {
return err
}
pkiApp := appModule.(*caddypki.PKI)
ca, err := pkiApp.GetCA(ctx, ash.CA)
if err != nil {
return err
}
// make sure leaf cert lifetime is less than the intermediate cert lifetime. this check only
// applies for caddy-managed intermediate certificates
if ca.Intermediate == nil && ash.Lifetime >= ca.IntermediateLifetime {
return fmt.Errorf("certificate lifetime (%s) should be less than intermediate certificate lifetime (%s)", time.Duration(ash.Lifetime), time.Duration(ca.IntermediateLifetime))
}
database, err := ash.openDatabase()
if err != nil {
return err
}
authorityConfig := caddypki.AuthorityConfig{
SignWithRoot: ash.SignWithRoot,
AuthConfig: &authority.AuthConfig{
Provisioners: provisioner.List{
&provisioner.ACME{
Name: ash.CA,
Challenges: ash.Challenges.toSmallstepType(),
Options: &provisioner.Options{
X509: ash.Policy.normalizeRules(),
},
Type: provisioner.TypeACME.String(),View on GitHub (pinned to 50e54ee279)
Solutions
- Lower the handler's `lifetime` below the intermediate's lifetime — e.g. `lifetime 12h` (default 12h works with the 7d default intermediate)
- Or raise the CA's intermediate lifetime first: set `intermediate_lifetime` on the CA (e.g. 720h) in the pki app config, then the leaf lifetime can go up
- Or provide your own external intermediate certificate to the CA (via `intermediate` key/cert), which bypasses this check
- Verify by validating config: `caddy validate --config Caddyfile`
Example fix
# before
{
acme_server {
lifetime 720h
}
}
# after (option A: shorter leaf)
{
acme_server {
lifetime 24h
}
}
# after (option B: longer intermediate, pki app JSON)
"pki": { "certificate_authorities": { "local": { "intermediate_lifetime": 2160 } } } Defensive patterns
Strategy: validation
Validate before calling
// Check lifetimes before loading acme_server config:
const defaultIntermediate = 7 * 24 * time.Hour
if intermediateLifetime == 0 { intermediateLifetime = defaultIntermediate }
if externalIntermediate == nil && leafLifetime >= intermediateLifetime {
return fmt.Errorf("leaf %s must be < intermediate %s", leafLifetime, intermediateLifetime)
} Prevention
- Document the 7-day default intermediate lifetime next to any `lifetime` setting
- When raising intermediate_lifetime, audit all acme_server handlers using that CA
- Run `caddy validate` after any lifetime changes
When it happens
Trigger: Configuring the ACME server handler with `lifetime 168h` (or any value >= 7d = 168h) while relying on Caddy's own intermediate certificate: `if ca.Intermediate == nil && ash.Lifetime >= ca.IntermediateLifetime` triggers. Also with intermediate_lifetime set low and lifetime not lowered to match.
Common situations: Raising certificate lifetime on an internal ACME server for device/iot clients that cache certs for weeks; setting lifetime to 720h for a private CA without realizing the stock intermediate lives 7 days; mixing lifetime/intermediate_lifetime units (Caddyfile durations are d/h/m/s).
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- intermediate certificate lifetime must be less than actual r
- acme challenge %q is not supported
- finalizing automatic HTTPS: %v
- configuring ACME DB: %v
- making folder for CA database: %v
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/42bd3ffda95cb568.
Report an issue: GitHub.