caddyserver/caddy · error

local_address must be a single address, not a port range

Error message

local_address must be a single address, not a port range

What it means

When `local_address` is set on the HTTP transport, Caddy parses it with `caddy.ParseNetworkAddressWithDefaults` and requires the result to be a single port (`PortRangeSize() > 1` rejected), because the dialer needs exactly one local address to bind for outbound connections.

Source

Thrown at modules/caddyhttp/reverseproxy/httptransport.go:239

	// Set a relatively short default dial timeout.
	// This is helpful to make load-balancer retries more speedy.
	if h.DialTimeout == 0 {
		h.DialTimeout = caddy.Duration(3 * time.Second)
	}

	dialer := &net.Dialer{
		Timeout:       time.Duration(h.DialTimeout),
		FallbackDelay: time.Duration(h.FallbackDelay),
	}

	if h.LocalAddress != "" {
		netaddr, err := caddy.ParseNetworkAddressWithDefaults(h.LocalAddress, "tcp", 0)
		if err != nil {
			return nil, err
		}
		if netaddr.PortRangeSize() > 1 {
			return nil, fmt.Errorf("local_address must be a single address, not a port range")
		}
		switch netaddr.Network {
		case "tcp", "tcp4", "tcp6":
			dialer.LocalAddr, err = net.ResolveTCPAddr(netaddr.Network, netaddr.JoinHostPort(0))
			if err != nil {
				return nil, err
			}
		case "unix", "unixgram", "unixpacket":
			dialer.LocalAddr, err = net.ResolveUnixAddr(netaddr.Network, netaddr.JoinHostPort(0))
			if err != nil {
				return nil, err
			}
		case "udp", "udp4", "udp6":
			return nil, fmt.Errorf("local_address must be a TCP address, not a UDP address")
		default:
			return nil, fmt.Errorf("unsupported network")
		}
	}

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Change local_address to a single port or no port (port 0/omitted lets the OS pick an ephemeral port)
  2. Remember local_address is the SOURCE address for connections to upstreams, not a listener

Example fix

# before
transport http {
	local_address 10.0.0.5:8000-8010
}
# after
transport http {
	local_address 10.0.0.5
}
Defensive patterns

Strategy: validation

Validate before calling

netaddr, err := caddy.ParseNetworkAddressWithDefaults(localAddr, "tcp", 0)
if err != nil {
	return err
}
if netaddr.PortRangeSize() > 1 {
	return fmt.Errorf("local_address must be single port")
}

Prevention

When it happens

Trigger: Configuring `transport http { local_address host:8000-8009 }` or any address whose port expands to multiple ports (ranges, or a service name mapping to multiple ports).

Common situations: Copy-pasting an upstream-style address (where port ranges are valid for load balancing) into local_address; misunderstanding local_address as the bind range for a listening server rather than the source address of outgoing proxy connections.

Related errors


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