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

  1. Confirm this is intended: the matching policy was configured with drop
  2. If the client should be served, add its SNI/domain to the policy's match allowlist or a serving policy that matches earlier
  3. Reorder policies so serving policies for known SNIs come before the catch-all drop policy
  4. 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

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


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