jeessy2/ddns-go · error
interface %s has no usable %s address
Error message
interface %s has no usable %s address
What it means
This error is thrown by getLocalAddrFromInterfaceByNetwork when the named network interface has at least one global-unicast address, but none of them match the requested address family (tcp4 or tcp6). The library binds the HTTP client's dialer to a specific interface and must pick an IP of the family matching the forced dial network; if the interface only has addresses of the other family (e.g. only IPv6 link-local/global addresses while 'tcp4' was requested), it cannot return a usable bind address and fails. Callers (CreateBoundNoProxyHTTPClient) log the failure and fall back to the default interface.
Source
Thrown at util/http_client_util.go:34
}
addrs, err := iface.Addrs()
if err != nil {
return "", fmt.Errorf("get interface %s addresses failed: %v", ifaceName, err)
}
hasGlobalUnicast := false
for _, addr := range addrs {
ipNet, ok := addr.(*net.IPNet)
if !ok || !ipNet.IP.IsGlobalUnicast() {
continue
}
hasGlobalUnicast = true
if isIPMatchedNetwork(ipNet.IP, network) {
return ipNet.IP.String(), nil
}
}
if hasGlobalUnicast && (network == "tcp4" || network == "tcp6") {
return "", fmt.Errorf("interface %s has no usable %s address", ifaceName, network)
}
return "", fmt.Errorf("interface %s has no usable global-unicast address", ifaceName)
}
func isIPMatchedNetwork(ip net.IP, network string) bool {
switch network {
case "tcp4":
return ip.To4() != nil
case "tcp6":
return ip.To16() != nil && ip.To4() == nil
default:
return true
}
}
func localTCPAddr(ip net.IP, network, ifaceName string) *net.TCPAddr {
addr := &net.TCPAddr{IP: ip}
if network == "tcp6" && ifaceName != "" {View on GitHub (pinned to 5874c2e666)
Solutions
- Check the interface's actual addresses (ip addr show <iface>) and pass the network that matches the addresses present: "tcp4" for an IPv4-only NIC, "tcp6" for an IPv6-only NIC
- Use network "tcp" (or empty/default) instead of "tcp4"/"tcp6" so any global-unicast address on the interface is accepted
- Add the missing address family to the interface (e.g. enable IPv6 or assign an IPv4 address) if the forced family is required
- Pick a different interface that has an address of the requested family
Example fix
// before
client := util.CreateBoundNoProxyHTTPClient("tcp4", "eth0") // eth0 is IPv6-only
// after
client := util.CreateBoundNoProxyHTTPClient("tcp", "eth0") // accept any family on eth0 Defensive patterns
Strategy: validation
Validate before calling
func hasFamilyAddr(ifaceName, network string) bool {
iface, err := net.InterfaceByName(ifaceName)
if err != nil { return false }
addrs, _ := iface.Addrs()
for _, a := range addrs {
if ipnet, ok := a.(*net.IPNet); ok && ipnet.IP.IsGlobalUnicast() {
if network == "tcp4" && ipnet.IP.To4() != nil { return true }
if network == "tcp6" && ipnet.IP.To4() == nil { return true }
if network != "tcp4" && network != "tcp6" { return true }
}
}
return false
}
// call util.CreateBoundNoProxyHTTPClient only if hasFamilyAddr(iface, network) Try / catch
localIP, err := util.GetLocalAddrFromInterface(ifaceName)
if err != nil {
log.Printf("interface %s lacks %s address, using default: %v", ifaceName, network, err)
client = util.CreateNoProxyHTTPClient(network) // fallback
} Prevention
- Inspect interface addresses (ip addr) before configuring a forced tcp4/tcp6 network
- Prefer "tcp" when you do not specifically need a single address family
- Prefer dual-stack interfaces when IPv6-only or IPv4-only operation is required
- Wrap client creation with a check of GetLocalAddrFromInterface output before relying on the bound client
When it happens
Trigger: Calling CreateBoundNoProxyHTTPClient("tcp4", ifaceName) on an interface whose addresses are all IPv6, or CreateBoundNoProxyHTTPClient("tcp6", ifaceName) on an interface with only IPv4 addresses. The interface must exist and have a global-unicast address, but not of the requested family.
Common situations: Configuring an IPv4-only box/interface for an IPv6-forced client or vice versa; dual-stack servers reached via a tunnel interface that only has one family; containers/veth pairs provisioned with only one address family; typos forcing 'tcp6' in config when the chosen NIC is IPv4-only.
Related errors
- interface %s has no usable global-unicast address
- 获取网卡 %s 地址失败: %v
- 网卡 %s 没有可用的单播地址
- 监听端口发生异常, 请检查端口是否被占用! %s
- 请求 dnsla 失败: %w
AI-assisted analysis of jeessy2/ddns-go@5874c2e666 (2026-09-03).
Data as JSON: /api/errors/093b95ace61f35d6.
Report an issue: GitHub.