jeessy2/ddns-go · error
网卡 %s 没有可用的单播地址
Error message
网卡 %s 没有可用的单播地址
What it means
GetLocalAddrFromInterface found the interface and read its addresses, but none of them were a global unicast address, so there is no IP the library can use as the client's bind address. Only addresses passing net.IP.IsGlobalUnicast() (public/universe scope, not loopback, link-local, or multicast) are accepted. This error means 'interface <name> has no usable unicast address'.
Source
Thrown at util/http_client_util.go:112
}
}
// GetLocalAddrFromInterface 根据网卡名称获取本地IP地址
func GetLocalAddrFromInterface(ifaceName string) (string, error) {
iface, err := net.InterfaceByName(ifaceName)
if err != nil {
return "", fmt.Errorf("找不到网卡 %s: %v", ifaceName, err)
}
addrs, err := iface.Addrs()
if err != nil {
return "", fmt.Errorf("获取网卡 %s 地址失败: %v", ifaceName, err)
}
for _, addr := range addrs {
if ipNet, ok := addr.(*net.IPNet); ok && ipNet.IP.IsGlobalUnicast() {
return ipNet.IP.String(), nil
}
}
return "", fmt.Errorf("网卡 %s 没有可用的单播地址", ifaceName)
}
// CreateHTTPClientWithInterface 创建绑定指定网卡的HTTP客户端
func CreateHTTPClientWithInterface(ifaceName string) *http.Client {
if ifaceName == "" {
return CreateHTTPClient()
}
localIP, err := GetLocalAddrFromInterface(ifaceName)
if err != nil {
Log("绑定网卡失败, 将使用默认网卡. 网卡: %s, 错误: %v", ifaceName, err)
return CreateHTTPClient()
}
localAddr := &net.TCPAddr{IP: net.ParseIP(localIP)}
boundDialer := newHTTPDialer(localAddr)
setLinuxBindToDevice(boundDialer, ifaceName)
transport := &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: func(ctx context.Context, network, address string) (net.Conn, error) {View on GitHub (pinned to 5874c2e666)
Solutions
- Check `ip addr show <iface>` — the interface needs a global-scope address; fix DHCP or assign a static address
- Select a different interface that has a real (global unicast) IP address
- Wait for DHCP/SLAAC to complete before initializing the client, or re-trigger the DHCP request
- If you intentionally bind to a link address, this API cannot help — remove the interface binding and use the default client
Example fix
// before
client := util.CreateHTTPClientWithInterface("eth1") // eth1 only has 169.254.10.20 (APIPA)
// after
dhclient eth1 # or assign a static global address, then:
client := util.CreateHTTPClientWithInterface("eth1") Defensive patterns
Strategy: validation
Validate before calling
func ifaceHasUsableAddr(name string) bool {
iface, err := net.InterfaceByName(name)
if err != nil { return false }
addrs, _ := iface.Addrs()
for _, a := range addrs {
if ipnet, ok := a.(*net.IPNet); ok && ipnet.IP.IsGlobalUnicast() { return true }
}
return false
}
// guard: if !ifaceHasUsableAddr(cfg.Interface) { alert/fix network first } Try / catch
_, err := util.GetLocalAddrFromInterface(ifaceName)
if err != nil {
log.Printf("interface %s has no global unicast address (%v); using default client", ifaceName, err)
client = util.CreateHTTPClient()
} Prevention
- Ensure DHCP succeeds or a static global address is assigned before binding
- Alert on APIPA/link-local-only addresses (169.254.0.0/16, fe80::/10) on monitored NICs
- Check `ip addr show` for a 'global' scope address, not just interface UP state
- Delay client creation until network-manager/DHCP reports the interface configured
When it happens
Trigger: Calling GetLocalAddrFromInterface/CreateHTTPClientWithInterface on an interface whose only addresses are loopback (127.0.0.1/::1), link-local (169.254.x.x, fe80::/10), or multicast-only — e.g. an interface that is UP but never got a DHCP lease.
Common situations: DHCP failure leaving only an APIPA 169.254.x.x address on the NIC; freshly created veth/bridge with no IP; VPN tun device up but unconfigured; point-to-point links with only link-local addressing.
Related errors
- interface %s has no usable %s address
- interface %s has no usable global-unicast address
- 获取网卡 %s 地址失败: %v
- 监听端口发生异常, 请检查端口是否被占用! %s
- 请求 dnsla 失败: %w
AI-assisted analysis of jeessy2/ddns-go@5874c2e666 (2026-09-03).
Data as JSON: /api/errors/d40561f70dda8bbc.
Report an issue: GitHub.