caddyserver/caddy · warning
dropping connection
Error message
dropping connection
What it means
Returned by the GetConfigForClient callback during a TLS handshake when the matched connection policy has Drop=true. It is not a malfunction: the operator explicitly configured a matcher + 'default_sni'-style policy whose action is to refuse the connection (e.g. block TLS for unknown SNI values), and Caddy aborts the handshake by returning this error.
Source
Thrown at modules/caddytls/connpolicy.go:134
}
getConfigForClient := func(hello *tls.ClientHelloInfo) (*tls.Config, error) {
// filter policies by SNI first, if possible, to speed things up
// when there may be lots of policies
possiblePolicies := cp
if indexedPolicies, ok := indexedBySNI[asciiServerNameForMatch(hello.ServerName)]; ok {
possiblePolicies = indexedPolicies
}
policyLoop:
for _, pol := range possiblePolicies {
for _, matcher := range pol.matchers {
if !matcher.Match(hello) {
continue policyLoop
}
}
if pol.Drop {
return nil, fmt.Errorf("dropping connection")
}
return pol.TLSConfig, nil
}
return nil, fmt.Errorf("no server TLS configuration available for ClientHello: %+v", hello)
}
tlsCfg := &tls.Config{
MinVersion: tls.VersionTLS12,
GetConfigForClient: getConfigForClient,
}
// enable ECH, if configured
if tlsAppIface, err := ctx.AppIfConfigured("tls"); err == nil {
tlsApp := tlsAppIface.(*TLS)
if tlsApp.EncryptedClientHello != nil && len(tlsApp.EncryptedClientHello.configs) > 0 {
// if no publication was configured, we apply ECH to all server names by default,View on GitHub (pinned to 50e54ee279)
Solutions
- Confirm this is intended: the matching policy was configured with drop
- If the client should be served, add its SNI/domain to the policy's match allowlist or a serving policy that matches earlier
- Reorder policies so serving policies for known SNIs come before the catch-all drop policy
- To distinguish from misconfig, log matched SNI and compare against the policy list
Example fix
# before
tls {
policies {
policy {
match {
sni *
}
drop
}
}
}
# after (serve known SNI, drop only unknown)
tls {
policies {
policy {
match {
sni example.com
}
}
policy {
match {
sni *
}
drop
}
}
} Defensive patterns
Strategy: validation
Validate before calling
# Before enabling a drop policy, enumerate the SNIs that will still be served: # compare your sni matchers against a DNS/inventory list of expected hostnames. caddy adapt --config Caddyfile --adapter caddyfile | jq '.. | .sni? // empty'
Prevention
- Order policies so explicit serve rules precede the catch-all drop
- Add monitoring: a spike in 'dropping connection' after deploy usually means an allowlist gap
- Document the allowlist wherever the drop policy is defined
When it happens
Trigger: A connection policy with "drop": true whose matchers (commonly sni) matched the incoming ClientHello. In Caddyfile: an @matcher-matched route using tls policies with drop, e.g. blocking connections whose SNI is not in an allowlist.
Common situations: Clients connecting by IP or with an SNI not in the allowlist get a TLS handshake failure; scanners and probes hitting the server; expected behavior after adding a drop policy but the operator forgot which SNIs are allowed.
Related errors
- no server TLS configuration available for ClientHello: %+v
- loading handshake matchers: %v
- connection policy %d: building standard TLS config: %s
- loading handshake context module: %v
- handshake context: %v
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/6a9ca7634dc2bff9.
Report an issue: GitHub.