XTLS/Xray-core · error

unable to set routes

Error message

unable to set routes

What it means

On Windows, Xray programs the TUN's routes via the winipcfg interface (LUID.SetRoutes). Failure wraps into this error. Typical base causes: insufficient privileges (route manipulation on Windows requires Administrator/SYSTEM), the wintun adapter being in a transient state, or conflicting route entries held by another process.

Source

Thrown at proxy/tun/tun_windows.go:116

			Metric:      0,
		}
		if ip.Addr().Is4() {
			has4 = true
			route.NextHop = netip.IPv4Unspecified()
		} else {
			has6 = true
			route.NextHop = netip.IPv6Unspecified()
		}
		routesMap[route] = struct{}{}
	}
	routesData := make([]*winipcfg.RouteData, 0, len(routesMap))
	for route := range routesMap {
		r := route
		routesData = append(routesData, &r)
	}
	err := t.luid.SetRoutes(routesData)
	if err != nil {
		return errors.New("unable to set routes").Base(err)
	}

	if len(t.options.Gateway) > 0 {
		addresses := make([]netip.Prefix, 0, len(t.options.Gateway))
		for _, address := range t.options.Gateway {
			addresses = append(addresses, netip.MustParsePrefix(address))
		}
		err := t.luid.SetIPAddresses(addresses)
		if err != nil {
			return errors.New("unable to set ips").Base(err)
		}
	}

	if has4 {
		ipif, err := t.luid.IPInterface(windows.AF_INET)
		if err != nil {
			return err
		}

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Run Xray as Administrator (or as a service under LocalSystem)
  2. Disconnect other VPN clients and retry
  3. Wait a few seconds after adapter creation/removal before restarting Xray
  4. Reboot if the Wintun adapter is stuck in a bad state, then retry

Example fix

# before
xray.exe run -c config.json  # normal user prompt

# after (elevated)
# right-click terminal -> Run as administrator
xray.exe run -c config.json
Defensive patterns

Strategy: retry

Validate before calling

// check elevation on windows before starting tun mode
if !isAdmin() { // tokenGetTokenInformation based check
	log.Fatal("run as administrator")
}

Try / catch

for attempt := 1; attempt <= 3; attempt++ {
	err := startTun(cfg)
	if err == nil || !strings.Contains(err.Error(), "unable to set routes") { break }
	time.Sleep(2 * time.Second) // let adapter/vpn teardown settle
}

Prevention

When it happens

Trigger: Running Xray as a normal user; the Wintun adapter still initializing; another VPN client holding overlapping routes; Windows NRPT or firewall products locking the route table.

Common situations: First run without elevation; running as a service under a non-privileged account; conflicts with commercial VPN software; rapid restarts where the old adapter instance is not yet torn down.

Related errors


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