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
- Change local_address to a single port or no port (port 0/omitted lets the OS pick an ephemeral port)
- 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
- Remember local_address is the outbound source address, single-port only
- Omit the port entirely to let the OS choose
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
- local_address must be a TCP address, not a UDP address
- unsupported network
- unsupported HTTP version: %s, supported version: %s
- unsupported network type: %s
- invalid IP address: '%s': %v
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/741a5e9237b46dda.
Report an issue: GitHub.