caddyserver/caddy · error
server %s: setting up TLS connection policies: %v
Error message
server %s: setting up TLS connection policies: %v
What it means
srv.TLSConnPolicies.Provision builds the TLS connection policies for the server: it resolves certificate selectors, client-auth settings, cipher suites, protocol versions, and loads the TLS app. Any policy that is malformed or references missing resources fails here, wrapped with the server name.
Source
Thrown at modules/caddyhttp/app.go:398
err := srv.Errors.Routes.Provision(ctx)
if err != nil {
return fmt.Errorf("server %s: setting up error handling routes: %v", srvName, err)
}
srv.errorHandlerChain = srv.Errors.Routes.Compile(errorEmptyHandler)
}
// provision the named routes (they get compiled at runtime)
for name, route := range srv.NamedRoutes {
err := route.Provision(ctx, app.Metrics)
if err != nil {
return fmt.Errorf("server %s: setting up named route '%s' handlers: %v", name, srvName, err)
}
}
// prepare the TLS connection policies
err = srv.TLSConnPolicies.Provision(ctx)
if err != nil {
return fmt.Errorf("server %s: setting up TLS connection policies: %v", srvName, err)
}
// if there is no idle timeout, set a sane default; users have complained
// before that aggressive CDNs leave connections open until the server
// closes them, so if we don't close them it leads to resource exhaustion
if srv.IdleTimeout == 0 {
srv.IdleTimeout = defaultIdleTimeout
}
if srv.ReadHeaderTimeout == 0 {
srv.ReadHeaderTimeout = defaultReadHeaderTimeout // see #6663
}
}
ctx.Context = oldContext
return nil
}
// Validate ensures the app's configuration is valid.
func (app *App) Validate() error {View on GitHub (pinned to 50e54ee279)
Solutions
- Read the wrapped error to find which policy option failed
- Use cipher/protocol names accepted by crypto/tls (e.g. TLS1.3 only has no configurable ciphers) and min<=max
- Verify cert IDs / client auth modules exist in this build; then `caddy validate`
Example fix
// before
{"protocol_min":"tls1.3","protocol_max":"tls1.2"}
// after
{"protocol_min":"tls1.2","protocol_max":"tls1.3"} Defensive patterns
Strategy: validation
Validate before calling
// reject obviously bad policies before load
for _, cp := range srvCfg.TLSConnPolicies {
if cp.ProtocolMin != "" && cp.ProtocolMax != "" && cp.ProtocolMin > cp.ProtocolMax {
return fmt.Errorf("protocol_min > protocol_max")
}
} Prevention
- Use tls.SupportedVersionsFrom / crypto/tls constants instead of hand-typed version strings
- Do not configure cipher suites for TLS 1.3-only policies (not configurable there)
- Validate in CI with the same Caddy version as production
When it happens
Trigger: A connection policy with an invalid cipher_suite or protocol_min/max, a client certificate verifier module that fails to load, a certificate selector referencing a nonexistent cert, or the TLS app not being available for a policy requiring it.
Common situations: Hardening TLS by copying cipher lists from other servers that include names Go's crypto/tls does not accept; setting protocol_min above protocol_max; referencing ACME-loaded certs by wrong ID.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- consolidating TLS connection policies for server %d: %v
- it is unnecessary to specify the TLS listener wrapper in the
- TLS listener wrapper can only be specified once
- loading certificate loader modules: %s
- provisioning automation policy %d: %v
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/8649878dede42ef1.
Report an issue: GitHub.