caddyserver/caddy · error

port range exceeds %d ports

Error message

port range exceeds %d ports

What it means

Caddy caps port ranges at maxPortSpan ports to prevent a single address from opening an unmanageable number of listeners. If (end - start) exceeds the cap, parsing fails with the limit in the message.

Source

Thrown at listeners.go:365

		end = uint64(defaultPort)
	} else {
		before, after, found := strings.Cut(port, "-")
		if !found {
			after = before
		}
		start, err = strconv.ParseUint(before, 10, 16)
		if err != nil {
			return NetworkAddress{}, fmt.Errorf("invalid start port: %v", err)
		}
		end, err = strconv.ParseUint(after, 10, 16)
		if err != nil {
			return NetworkAddress{}, fmt.Errorf("invalid end port: %v", err)
		}
		if end < start {
			return NetworkAddress{}, fmt.Errorf("end port must not be less than start port")
		}
		if (end - start) > maxPortSpan {
			return NetworkAddress{}, fmt.Errorf("port range exceeds %d ports", maxPortSpan)
		}
	}
	return NetworkAddress{
		Network:   network,
		Host:      host,
		StartPort: uint(start),
		EndPort:   uint(end),
	}, nil
}

// SplitNetworkAddress splits a into its network, host, and port components.
// Note that port may be a port range (:X-Y), or omitted for unix sockets.
func SplitNetworkAddress(a string) (network, host, port string, err error) {
	beforeSlash, afterSlash, slashFound := strings.Cut(a, "/")
	if slashFound {
		network = strings.ToLower(strings.TrimSpace(beforeSlash))
		a = afterSlash
		if IsUnixNetwork(network) || IsFdNetwork(network) {

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Narrow the range to only the ports actually served (e.g. ':8080-8085').
  2. Bind the specific ports you need as separate listen directives instead of one giant range.
  3. Remember a port is not a wildcard: listening on all 65535 ports is neither supported nor advisable.

Example fix

// before
{
  listen :1-65535
}
// after
{
  listen :80
  listen :443
}
Defensive patterns

Strategy: validation

Validate before calling

const maxPortSpan = 64 // mirror caddy's cap

func spanOK(start, end uint64) bool { return end-start <= maxPortSpan }

Prevention

When it happens

Trigger: Wide ranges such as ':1-65535' or ':1000-99999' (already caught by uint16, but ':1-65535' passes numeric checks) where the span exceeds maxPortSpan.

Common situations: Users trying to bind all ports or emulate a wildcard listener; misreading a CIDR-style '0-65535' shorthand; copy-paste from firewall rule syntax.

Related errors


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