caddyserver/caddy · error

server block %d, key %d (%s): determining listener address:

Error message

server block %d, key %d (%s): determining listener address: %v

What it means

After a site key parsed successfully, listenersForServerBlockAddress failed for it: the combination of the key's scheme/port and the block's bind addresses/protocols produced an invalid listener setup. The message identifies the exact server block index, key index, and key text.

Source

Thrown at caddyconfig/httpcaddyfile/addresses.go:110

		// implied by the server block to the keys of the server block which
		// will be served by them; this has the effect of treating each
		// key of a server block as its own, but without having to repeat its
		// contents in cases where multiple keys really can be served together
		addrToProtocolToKeyWithParsedKeys := map[string]map[string][]keyWithParsedKey{}
		for j, key := range sblock.block.Keys {
			parsedKey, err := ParseAddress(key.Text)
			if err != nil {
				return nil, fmt.Errorf("parsing key: %v", err)
			}
			parsedKey = parsedKey.Normalize()

			// a key can have multiple listener addresses if there are multiple
			// arguments to the 'bind' directive (although they will all have
			// the same port, since the port is defined by the key or is implicit
			// through automatic HTTPS)
			listeners, err := st.listenersForServerBlockAddress(sblock, parsedKey, options)
			if err != nil {
				return nil, fmt.Errorf("server block %d, key %d (%s): determining listener address: %v", i, j, key.Text, err)
			}

			// associate this key with its protocols and each listener address served with them
			kwpk := keyWithParsedKey{key, parsedKey}
			for addr, protocols := range listeners {
				protocolToKeyWithParsedKeys, ok := addrToProtocolToKeyWithParsedKeys[addr]
				if !ok {
					protocolToKeyWithParsedKeys = map[string][]keyWithParsedKey{}
					addrToProtocolToKeyWithParsedKeys[addr] = protocolToKeyWithParsedKeys
				}

				// an empty protocol indicates the default, a nil or empty value in the ListenProtocols array
				if len(protocols) == 0 {
					protocols[""] = struct{}{}
				}
				for prot := range protocols {
					protocolToKeyWithParsedKeys[prot] = append(
						protocolToKeyWithParsedKeys[prot],

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Use the key text in the message to find the block, then read the wrapped error: it will be one of the scheme/port/bind errors from listenersForServerBlockAddress
  2. For convention violations, align scheme and port (http with 80/http_port, https with 443/https_port)
  3. Replace ws:// or wss:// keys with http:// or https:// — WebSocket works over both in Caddy
  4. Fix or remove the bind directive value mentioned in the wrapped error

Example fix

# before
http://example.com:443 {
}
# after
https://example.com:443 {
}
Defensive patterns

Strategy: validation

Validate before calling

addr, err := httpcaddyfile.ParseAddress(key)
if err != nil { return err }
addr = addr.Normalize()
switch addr.Scheme {
case "ws", "wss", "ftp", "tcp":
    return fmt.Errorf("scheme %q not allowed in site address", addr.Scheme)
}

Prevention

When it happens

Trigger: Causes include ws/wss schemes, scheme/port convention violations (https on the http port or vice versa), an unsupported scheme, a bind address that fails SplitNetworkAddress/ParseNetworkAddress, or bind protocols invalid for the address.

Common situations: Site label like 'http://example.com:443' (convention violation), 'ws://' keys, or a bind directive with a malformed address such as 'bind tcp/' or an unparseable network prefix.

Related errors


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