caddyserver/caddy · error

end port must not be less than start port

Error message

end port must not be less than start port

What it means

After both ports parse, Caddy rejects ranges where end < start, e.g. 8090-8080. Port ranges in Caddy are ascending only, and both bounds are inclusive.

Source

Thrown at listeners.go:362

	var start, end uint64
	if port == "" {
		start = uint64(defaultPort)
		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 {

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Swap the bounds so the smaller port comes first: ':8080-8090'.
  2. In generators, sort the pair before formatting the range.
  3. A single port (no hyphen) avoids range-ordering issues entirely.

Example fix

// before
{
  listen :8090-8080
}
// after
{
  listen :8080-8090
}
Defensive patterns

Strategy: validation

Validate before calling

func orderedRange(start, end uint64) (uint64, uint64) {
    if end < start { return end, start }
    return start, end
}

Prevention

When it happens

Trigger: Any address like ':8090-8080', ':443-80', or config generation that swaps min/max when a user enters an inverted range.

Common situations: Users writing 'high-low' naturally when they mean 'any port in this span'; automation that concatenates two user-supplied numbers without ordering them.

Related errors


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