caddyserver/caddy · error
consolidating TLS connection policies for server %d: %v
Error message
consolidating TLS connection policies for server %d: %v
What it means
Caddyfile adaptation failed while merging/normalizing the TLS connection policies collected for one HTTP server (srv%d). consolidateConnPolicies tries to combine policies that match the same SNI set; if two such policies disagree on a setting that cannot be safely merged (e.g. different ALPN, cipher suites, protocols, client auth), it returns an error that gets wrapped with the server index.
Source
Thrown at caddyconfig/httpcaddyfile/httptype.go:1105
// catch-all/default policy if there isn't one already (it's
// important that it goes at the end) - see issue #3004:
// https://github.com/caddyserver/caddy/issues/3004
// TODO: maybe a smarter way to handle this might be to just make the
// auto-HTTPS logic at provision-time detect if there is any connection
// policy missing for any HTTPS-enabled hosts, if so, add it... maybe?
if addressQualifiesForTLS &&
!hasCatchAllTLSConnPolicy &&
(len(srv.TLSConnPolicies) > 0 || !autoHTTPSWillAddConnPolicy || defaultSNI != "" || fallbackSNI != "") {
srv.TLSConnPolicies = append(srv.TLSConnPolicies, &caddytls.ConnectionPolicy{
DefaultSNI: defaultSNI,
FallbackSNI: fallbackSNI,
})
}
// tidy things up a bit
srv.TLSConnPolicies, err = consolidateConnPolicies(srv.TLSConnPolicies)
if err != nil {
return nil, fmt.Errorf("consolidating TLS connection policies for server %d: %v", i, err)
}
srv.Routes = consolidateRoutes(srv.Routes)
servers[fmt.Sprintf("srv%d", i)] = srv
}
if err := applyServerOptions(servers, options, warnings); err != nil {
return nil, fmt.Errorf("applying global server options: %v", err)
}
return servers, nil
}
// sniNames returns the server names a connection policy's sni matcher matches.
// The bool is false when the policy has no sni matcher, or when it does not
// decode - the latter is unexpected enough to warn about rather than silently
// skip, since callers use it to decide whether a hostname needs shielding.
func sniNames(cp *caddytls.ConnectionPolicy, what string, warnings *[]caddyconfig.Warning) ([]string, bool) {View on GitHub (pinned to 50e54ee279)
Solutions
- Make the tls settings identical for all site blocks that share the same hostnames (or delete the duplicated ones so a single policy remains)
- Use different ports or explicit `bind`/server splits so conflicting policies land on different servers instead of being consolidated
- Set the conflicting option once in the global `default_sni`/`fallback_sni` options rather than per site
- Check the server index (srv0, srv1, ...) in the message to identify which listen group has the clash
Example fix
# before
example.com {
tls {
protocols tls1.2
}
}
example.com:8443 {
tls {
protocols tls1.3
}
}
# after
example.com {
tls {
protocols tls1.2 tls1.3
}
} Defensive patterns
Strategy: validation
Validate before calling
# Deduplicate tls settings per hostname before adapting; a quick lint pass:
# (conceptual, in your config pipeline)
assert len({block.tls_settings for block in blocks if block.host == host}) <= 1 Try / catch
if err := caddyfileAdapt(cfg); err != nil {
if strings.Contains(err.Error(), "consolidating TLS connection policies") {
// surface which server index and dedupe tls blocks
}
} Prevention
- Keep each hostname's tls block in one place (snippet) and import it
- Run `caddy adapt --config Caddyfile` in CI to catch consolidation conflicts before deploy
- Avoid mixing global default_sni/fallback_sni with per-site tls overrides
When it happens
Trigger: A site block whose server (same listen port group) ends up with two or more tls connection policies covering overlapping/same SNI matchers with incompatible settings — e.g. one block sets `tls { protocols }` and another with the same hostname sets `tls { ciphers }` or different `alpn`, so consolidation cannot reconcile them. Also any error surfaced by the per-field conflict checks inside consolidateConnPolicies (errors 127-135).
Common situations: Multiple site blocks on the same port declaring different `tls` settings for the same domain, a global `tls`/`default_sni` global option combined with per-site `tls` blocks that conflict, or copy-pasted site configs where one block has `tls internal` and another has explicit ciphers for the same names.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- applying global server options: %v
- server listening on %v is HTTP, but attempts to configure TL
- two policies with same match criteria have conflicting ALPN:
- two policies with same match criteria have conflicting ciphe
- two policies with same match criteria have conflicting clien
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/174c83d936b1b61e.
Report an issue: GitHub.