XTLS/Xray-core · error

outbound interface cannot be the TUN interface

Error message

outbound interface cannot be the TUN interface

What it means

When a fixed outbound interface is configured for the tun proxy, Xray verifies it is not the TUN interface itself. Binding outbound traffic to the TUN would create a routing loop (packets re-entering the tunnel). The check compares the resolved interface index against the TUN link index and fails on equality.

Source

Thrown at proxy/tun/tun_linux.go:346

				return
			}
			if updater != nil {
				updater.Update()
			}
		case <-t.routeMonitorStop:
			return
		}
	}
}

func findOutboundInterface(tunIndex int, fixedName string) (*net.Interface, error) {
	if fixedName != "" {
		iface, err := net.InterfaceByName(fixedName)
		if err != nil {
			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) {

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Point the fixed interface at the physical NIC (e.g. "eth0", "wlan0") instead of the TUN name
  2. Remove the fixed interface setting to let Xray auto-detect the default-route interface
  3. Verify with `ip link` which name belongs to the physical adapter

Example fix

// before
"interface": "tun0"

// after
"interface": "eth0"
Defensive patterns

Strategy: validation

Validate before calling

if cfg.OutboundInterface != "" {
	iface, err := net.InterfaceByName(cfg.OutboundInterface)
	if err != nil { log.Fatalf("unknown interface %q", cfg.OutboundInterface) }
	if iface.Name == cfg.TunName {
		log.Fatal("outbound interface must not be the TUN interface")
	}
}

Prevention

When it happens

Trigger: Configuring the tun inbound's "interface"/outbound bind setting to the same name as the TUN device (e.g. both "tun0"); wildcard or guessed names that happen to resolve to the TUN.

Common situations: Copy-pasted configs where someone set interface to the only NIC they see, which is the freshly created TUN; renaming the physical NIC so an old name now matches the TUN.

Related errors


AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15). Data as JSON: /api/errors/0071797880095b57. Report an issue: GitHub.