jeessy2/ddns-go · error
interface %s has no usable global-unicast address
Error message
interface %s has no usable global-unicast address
What it means
This error is thrown by getLocalAddrFromInterfaceByNetwork when the named interface either does not exist as named, has no global-unicast addresses at all, or has no usable address for the requested family. It is the fallback message after checking all addresses; error 65 is the family-specific variant, this one fires when there was no global-unicast address found (hasGlobalUnicast == false) or the network is not tcp4/tcp6. The library needs a bindable IP to pin the HTTP client to the interface and cannot proceed without one.
Source
Thrown at util/http_client_util.go:36
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 != "" {
addr.Zone = ifaceName
}View on GitHub (pinned to 5874c2e666)
Solutions
- Verify the interface exists and has a global-unicast address: ip addr show <iface>; look for a global scope inet/inet6 address
- Bring the interface up and wait for DHCP/SLAAC to assign an address before creating the client
- Choose a different interface that has a global unicast address
- If you need family-specific behavior use "tcp4" or "tcp6" so the family-specific error path (and matching logic) applies
Example fix
// before
client := util.CreateBoundNoProxyHTTPClient("tcp", "docker0") // bridge without global addr
// after
client := util.CreateBoundNoProxyHTTPClient("tcp", "eth0") // NIC with a global unicast address Defensive patterns
Strategy: validation
Validate before calling
func ifaceHasGlobalAddr(ifaceName string) bool {
iface, err := net.InterfaceByName(ifaceName)
if err != nil { return false }
if iface.Flags&net.FlagUp == 0 { return false }
addrs, err := iface.Addrs()
if err != nil { return false }
for _, a := range addrs {
if ipnet, ok := a.(*net.IPNet); ok && ipnet.IP.IsGlobalUnicast() { return true }
}
return false
}
// only pass ifaceName to CreateBoundNoProxyHTTPClient if ifaceHasGlobalAddr(ifaceName) Try / catch
_, err := util.GetLocalAddrFromInterface(ifaceName)
if err != nil {
log.Printf("cannot bind to %s: %v; falling back to default routing", ifaceName, err)
client = util.CreateNoProxyHTTPClient(network)
} Prevention
- Ensure the target interface is UP and holds a global-scope address before binding
- Avoid binding to bridges/tun devices that have no assigned IP
- Monitor interface address state (DHCP lease expiry) in long-running services
- Log and compare against `ip addr show` output when debugging binding failures
When it happens
Trigger: Calling CreateBoundNoProxyHTTPClient with a network like "tcp" on an interface whose addresses are all loopback/link-local/multicast, or an interface that exists but has no global unicast addresses (e.g. a down interface, a bridge with no assigned IP).
Common situations: Binding to docker0/bridge interfaces without assigned IPs; interfaces that are DOWN; VPN/tunnel adapters with only link-local addresses; passing a network value other than tcp4/tcp6 while the interface also lacks addresses; environments where the NIC lost its DHCP lease.
Related errors
- interface %s has no usable %s address
- 获取网卡 %s 地址失败: %v
- 网卡 %s 没有可用的单播地址
- 监听端口发生异常, 请检查端口是否被占用! %s
- 请求 dnsla 失败: %w
AI-assisted analysis of jeessy2/ddns-go@5874c2e666 (2026-09-03).
Data as JSON: /api/errors/b02212050a36d5e0.
Report an issue: GitHub.