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

  1. Read the wrapped error to find which policy option failed
  2. Use cipher/protocol names accepted by crypto/tls (e.g. TLS1.3 only has no configurable ciphers) and min<=max
  3. 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

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

Related errors


AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15). Data as JSON: /api/errors/8649878dede42ef1. Report an issue: GitHub.