XTLS/Xray-core · error
no usable outbound interface found
Error message
no usable outbound interface found
What it means
With no fixed interface configured, Xray scans IPv4 then IPv6 route tables for a usable default-route interface that is not the TUN. If neither family yields a candidate, startup fails with this error. The machine effectively has no default route Xray can use to reach the internet.
Source
Thrown at proxy/tun/tun_linux.go:361
return nil, err
}
if iface.Index == tunIndex {
return nil, errors.New("outbound interface cannot be the TUN interface")
}
return iface, nil
}
for _, family := range []int{
netlink.FAMILY_V4,
netlink.FAMILY_V6,
} {
iface, err := findDefaultInterface(family, tunIndex)
if err == nil {
return iface, nil
}
}
return nil, errors.New("no usable outbound interface found")
}
func findDefaultInterface(family int, tunIndex int) (*net.Interface, error) {
routes, err := netlink.RouteList(nil, family)
if err != nil {
return nil, err
}
var selected *net.Interface
selectedMetric := -1
for _, route := range routes {
if route.Dst != nil {
ones, _ := route.Dst.Mask.Size()
if ones != 0 {
continue
}
}View on GitHub (pinned to 7d214f8b09)
Solutions
- Restore a default route: `ip route add default via <gw> dev <phys>`
- Configure the fixed outbound interface explicitly so auto-detection is skipped
- In containers, run with a proper network stack (e.g. docker --network with a gateway)
Example fix
# before: no default route ip route # only link-scope routes # after ip route add default via 192.168.1.1 dev eth0 # then start xray
Defensive patterns
Strategy: validation
Validate before calling
func hasDefaultRoute() bool {
for _, f := range []int{netlink.FAMILY_V4, netlink.FAMILY_V6} {
routes, err := netlink.RouteList(nil, f)
if err != nil { continue }
for _, r := range routes {
if r.Dst == nil { return true }
}
}
return false
}
if !hasDefaultRoute() { log.Fatal("no default route; fix networking first") } Prevention
- Verify `ip route show default` exists before enabling tun mode
- Pin the outbound interface to skip auto-detection
- In containers, attach a network with a gateway
When it happens
Trigger: A VM/container with only a linked-scope or loopback setup; default route deleted; all default routes pointing at the just-created TUN; netlink route listing failing (permissions) so both family probes error.
Common situations: Minimal containers (docker default bridge removed), air-gapped test environments, misconfigured network namespaces, or a previous VPN client that replaced the default route and did not restore it.
Related errors
- invalid system route {cidr}
- failed to add system route {cidr}
- failed to delete system route
- outbound interface cannot be the TUN interface
- physical default route not found
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/0319eedb9c72750f.
Report an issue: GitHub.