mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-10-15 05:42:07 +00:00
[GH-ISSUE #3134] Windows Xray can bind to a disconnected uplink adapter and fail with WSAEHOSTUNREACH #1455
Open
opened 2026-10-13 20:42:46 +00:00 by bsakaguchi
·
1 comment
No Branch/Tag specified
dev
feat/otp-login
feat/api-tests
fix/show-locked-xray-settings-page-for-servers-without-write-access
fix/serialize-log-record-writes-and-pin-log-date-format-locale
fix/libagw-review-fixes
fix/ios-xray-ipv6-leak
fix/macos-xray-ipv6-leak
feat/add-support-include-split-tunnel
fix/win-xray-app-split-tunneling
fix/bug-when-saving-after-canceling
fix/xray-reconnect-crash
fix/share-empty-config-on-ssh-timeout
fix/ssh-credentials-input
fix/updater-verify-signature
fix/async-ssh-threading
fix/xray-check-inet-and-liveness-monitor
fix/selfhosted-server-installations
feat/add-support-ikev2-macos
fix/icons-different-color-themes
feat/add_support_arm_windows
feat/add-deep-link
feat/fixed-push-notifications-on-VPN-connect-disconnect-2
feat/implement-QR-code-generation-and-scanning
feat/file-password-protection
feature/add-local-proxy
feat/add-support-split-tunnel-macos
feat/tests
fix/android-register-unacknowledged-purchase
fix/share_on_linux
mirroring-to-outside
feat_copy_docker_configs
feat/self-diagnostics-log
feat/amnezia-free-vless-switch
fix/conan_build_android_on_win
fix/linux-reconnect-dns-reliability
fix/windows-connection-stability
fix/linux-reconnect-refactoring
fix/ios-groupidentifier-order
feat/xray-subscription-link
fix/minor-fixes
fix/xray-config-inplace-edit
feat/amnezia-sdk-typed-api
feat/amnezia-sdk-integration
feat/force-update-native
refactor/marketplace-update-popup
feat/force-update
fix/valnurability_dev
chore-xcode-version
fix/empty-i1-i5
build_qt_6_10_1
master
feat/protocol-selection
fix/openvpn_install
feat/locations_change
feat/locations_change_rework
feature/local-proxy-integration
fix/filepicker_atv
fix_valnurability
fix/macos-ne-codesign-4.8.19.0
temp-branch-for-testing
fix/rebased_4_8_19_linux_fix_error
feat/proxy-storage-cache
fix/zeroed-params
fix/killswitch-blocknets-linux
update/translation_RU
fix/self_hosted_reinstall_error
feat/selfhosted-dns
fix/agp_version_up
feat/switch_to_alive_protocol
feat/support_multipeer
server_scripts_update
fix/extended-vless-configuration
chore/apple-ci-cd-macos-versions
feat/add-telemt
fix/android_keystore_read_error
feat/add-mtproxy
chore/bump-qt-version
fix/make_dbus_async
feature/dns
rebase/apple-tv-target-on-conan
fix/outbound_freedom_xray_with_dns_fix
feat/apk_support
feat/fallback-proxy
feat/apple-tv-target
fix/dns_reconnection_issue
feat/fixed-push-notifications-on-VPN-connect-disconnect
fix/linux-firewall
docker-regional-locks
appstore-review-popup
feat/storekit2
fix/uninstall-split-tunnelling-driver
revert-2376-chore/license-file
support_16kb_android
bump_version
feat_add_review_android
bugfix/translation-absence-on-subscription-key-page
feat/location-separation-by-region
bugfix/text-moving-when-resing-window
fix_backup
feature/add-purchase-android
bugfix/moved-text-while-resizing-window
bugfix/incorrect-killswitch-restore-from-backup
fix/backup-exclude-secondary-api-configs
feat/proxy-fields-for-dev-console
bugfix/ovpn-ios-fix
bugfix/linux-bundle-libraries
fix/xray-app-split-win
fix/upload-to-s3
chore/add-release-date-upload
feat_add_webview_support
feature/configuration-transfer-through-qr
feat/bot-key-unlink-device
fix/ad-link-lang-support
fix/qsecuresettings-with-android
feat/add-support-arm64-win
spanish-translations
fix/context-menu
feat/add-system-dns-support
fix/qt6-9-support
fix/qt6_9_support
bugfix/strict-killswitch-ui
android-7
chore/minor-bugfixes
feature/awg-net-fix-macos-wakeup
fixbug/ios18
bugfix/ios-ne-crash
fix/linux-tray-quit-button
cryptpad-support
bugfix/disable-linux-killswitch
fix/minor-ui-fixes
feature/setup-guid-tun2socks
feature/linux-ipsec
feature/ipsec-linux
refactoring/server-config-in-classes
feature/macos-ipsec
fix/ui-fixes-after-merge-with-d20ed4a
chore/focus_control_after_qt_6.9_migration
feature/integrate-xray-as-a-library
maxos-awg-fix
feature/add-new-awg-docker-image
chore/update-3rd-prebuild
feature/test-news
fix/api-conf-files
bugfix/split-tunneling-with-api-config
bugfix/ios-awg-new-fields
feature/special-handshake-2
feat/xray-api-support
fix/desktop-entry
bugfix/shadowsocks-cipher-setting-not-changing
feature/update-tap
bugfix/openvpn_import_fix
feature/ability-to-change-port-after-installing-xray
bugfix/strict-mode-ovpn
bugfix/win-ipv6-ovpn
bugfix/subnet-adress-setting
exception-podman-docker
bugfix/fix-listviewtype-scrolling
bugfix/win-disabled-ipv6
bugfix/win-ipv6-disabled-ovpn
feature/killswitch-strict-mode
feature/awg-network-check
feature/empty-split-tunneling-list
feature/support-info
chore/update-go-version
checking-Linux-version
update_server_scripts
bugfix/button-selection-easy-setup-page
feature/old-api-proxy
patch/user-checking
fix/correcting-version
support-podman
support_podman
user-checking-patch
feature/check-docker-version
feature/allowed-dns-list
without_lsof
chore/error-body
Update-amneziavpn_ru_RU
shiroow-patch-8
shiroow-patch-7
shiroow-patch-6
shiroow-patch-5
shiroow-patch-4
shiroow-patch-3
shiroow-patch-2
shiroow-patch-1
check_sudo_permissions
feature/euphoria
add_next_octet_to_ip_settings
bugfix/mobile-controllers-init
euphoria
bugfix/android-crush
feature/macox-network-extension
bugfix/pre-release-hotfixes
bugfix/ipsec-pfs
chore/ios-site-links
checking_sudo_permissions
feature/android-tv
improve_navigation_cpp
bugfix/linux-firewall-install
fixbug/wireguard-handshake-time
ReadmeRu_full
feature/xray-user-management
feature/subscription-end-date
chore/clang-format
feature/ru-in-readme
chore/increased-api-timeout
chore/deploy-workflow
bugfix/services-list-scroll
wheel_group_suppor
chore/bump-xcode-version
fixbug/mac-network-extension
feature/android-gpb
feature/page-home-drawer-country-selection
checking-sudo-users
bugfix/service-info-from-response
fixbug/build-macos-ne-2
android-qt-6.7.3
fixbug/build-macos-ne
bugfix/wg-windows-log-folder
feature/psk-key-api-request
bugfix/user-management-qml-warnings
fix/macos-network-extension
fixbug/macos-NE-build
bugfix/fixed-isDevEnv-initialization
bugfix/revert-ios-ovpn
feature/tun2socksSrv
fix/disable_singleapp
feature/awg-wg-name-resolving
feature/disable-dhcp
bugfix/allowed-ips-old-configs
feature/goodbyedpi
feature/add-exception-log
refactoring/remove-ipv6-from-default-routes
refactoring/singleapplication-submodule
macos-dirty-build
test/gateway
Update-amneziavpn_fa_IR.ts
bugfix/ipsec-win
fix/xray-custom-port
improve-tab-navigation
test-win-11
feature/android-tv-remote-control-support
KsZnak-patch-1
feature/awg-wg-qr
bugfix/fix-loopback-splittunel
fix/setup_host_firewall
feature/android-xray
feature/openvpn-pass
feature/connection-string
fix/clickable-errors
bugfix/api_1100_fix
feature/graphview
testsvg
feature/update-win-awg
feature/open-as-amnezia
feature/update-mozilla-upstream
bugfix/qr-code-cutting
feature/native-wg-psk
test/awg-centos
bugfix/hide_error
feature/add-uninstaller-checkbox
bugfix/cancel-button-on-install-page
bugfix/anchors-page-home-warning
awg-udptlspipe
button-focus-fix
revert-677-fix/logger
bugfix/Revert_PR_596
bugfix/allowed-ips-api-configs
bugfix/on-escape-pressed
feature/auto-scroll-for-server-selection-list
fix/ui-fixes
translations/update_fa_IR.ts
feature/new-awg-docker-container
bugfix/awg_ipv6_fix
feature/tab-navigation
fix/username-no-autocapitalization
sure
refactoring/servers-model-cleanup
feature/wg-mtu-setup-ios
3rd_adaptation_to_diff_OS
sudo_not_found
test/docker-ce
bugfix/double_clear_server_from_amnezia
fix/android
client/3rd-prebuilt
revert-559-KsZnak-translation-ru-ex
KsZnak-translation-ru-ex
KsZnak-br1
KsZnak-text-change
feature/api-awg
feature/error-code-output
feature/win_x32_builds
text/debug-output
feature/ovpn3-desktop-cli
bugfix/secureqsettings-deadlock
refactoring/change-settings-when-connected
files_check
ArchLinux-support
second_adaptation_to_diff_os
sudo
refactoring/android-build
adaptation_to_different_os
feature/online_installer_for_v4
update_to_r2
bugfix/return-after-installation
feature/custom_drawer_component
bugfix/split-tunneling
bugfix/existing-awg-container
revert-370-feature/custom_drawer_component
bugfix/adapted_awg_questiondrawer
bugfix/updated_drawer_height_pageserverdata
bugfix/translated_new_source_strings_to_chinese
feature/split-tunneling-config
feature/accessibility-support
branch_connectivity_change_fix
feature/ikev2_android
android_ss_transport
bugfix/macos_fixes
feature/nextcloud-support
feature/macos_network_extension
android_pt_transport_source
feature/ios-openvpn3-pluggable-transport-Cloak
bugfix/cloak_for_desktops_fix
arm-build-macos
fix-macos-build-brew
bugfix/ios-build-openvpnadapter-from-source
feature/download-native-wireguard-config-on-connect
feature/v2ray-container
bugfix/dpkg-busy-checking-stuck
feature/online-installer
dev-killswitch
dev-netadapters
5.0.3.0
5.0.2.1
5.0.2.0
5.0.1.5
5.0.0.5
5.0.0.2
4.8.21.0
4.8.19.0
4.8.18.0
4.8.17.0
4.8.16.0
4.8.15.4
4.8.15.0
4.8.14.5
4.8.14.1
4.8.12.9
4.8.12.8
4.8.12.7
4.8.12.6
4.8.11.4
4.8.11.3
4.8.11.2
4.8.11.1
4.8.11.0
4.8.10.0
4.8.9.2
4.8.9.1
4.8.9.0
4.8.8.3
4.8.8.2
4.8.8.1
4.8.7.2
4.8.7.1
4.8.7.0
4.8.6.0
4.8.5.0
4.8.4.5
4.8.4.4
4.8.4.3
4.8.4.2
4.8.4.1
4.8.4.0
4.8.3.2
4.8.3.1
4.8.2.3
4.8.1.9
4.8.1.0
4.8.0.5
4.7.0.0
4.6.0.3
4.6.0.1
4.5.3.0
4.5.0.0
4.4.0.0
4.3.0.0
4.2.1.0
4.2.0.1
4.1.2.0_cloak_pt_experimental
4.1.0.1
4.0.8
3.1.0
3.0.8
3.0.7
3.0.5
2.1.2
2.1.0
2.0.10
2.0.9
2.0.8
2.0.7
2.0.6
2.0.5
2.0.1
2.0
1.9.1
1.9
1.8
1.7
1.6
1.5
1.4
1.3
1.2
1.1
1.0
No labels
pull-request
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".
No due date set.
Dependencies
No dependencies set.
Reference
amnezia-vpn/amnezia-client#1455
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @alfateam22 on GitHub (Sep 7, 2026).
Original GitHub issue: https://github.com/amnezia-vpn/amnezia-client/issues/3134
Describe the bug
On Windows 10, AmneziaVPN 5.0.1.5 can select a disconnected network adapter as the uplink for the embedded Xray core when multiple adapters/gateways are present.
In the reproduced case, the workstation had working Internet over Ethernet (
ifIndex 11), while Wi-Fi (ifIndex 8) was disconnected but still present in the adapter/gateway enumeration. Windows' best route to the remote Xray server used Ethernet, but Amnezia's Xray service selected Wi-Fi instead:The embedded Xray then repeatedly failed before any TCP SYN left the workstation:
transport/internet/tcp: dialing TCP to tcp::8443
...
connectex: A socket operation was attempted to an unreachable host.
The Amnezia UI still reached Connected, because the local TUN/tun2socks/Xray stack started successfully, but browser traffic did not pass.
A direct Test-NetConnection to the same remote endpoint/port succeeded outside the tunnel, and a server-side packet capture during the failed Amnezia attempt saw 0 packets on TCP 8443.
To Reproduce
Windows 10 machine with Internet over Ethernet.
Keep a Wi-Fi adapter present but disconnected (not administratively disabled). Multiple gateway-bearing/virtual adapters may also be present.
Import/connect an Xray/VLESS/REALITY profile in AmneziaVPN 5.0.1.5.
Enable debug logging and inspect the service log.
Observe that Amnezia Xray may select the disconnected Wi-Fi interface instead of the actual route to the remote Xray server:
[xray] using uplink interface: "wireless_32768" ( 8 )
Internet access through the Xray profile fails with local Windows connectex ... unreachable host errors.
Administratively disable only the disconnected Wi-Fi adapter.
Reconnect the same Xray profile.
Observe that Amnezia now selects the working Ethernet interface:
[xray] using uplink interface: "ethernet_32772" ( 11 )
The same Xray profile then works end-to-end; normal web browsing succeeds and public egress is confirmed through the remote Xray server.
Expected behavior
For Xray outbound sockets, AmneziaVPN should select the interface corresponding to the Windows best route to the actual remote Xray server endpoint, rather than a generic/last gateway-bearing adapter.
A disconnected adapter should not be used as the forced IP_UNICAST_IF for the Xray outbound socket when Windows would route the destination through a different active interface.
Log files
Sanitized relevant excerpts:
Failed state:
[xray] using uplink interface: "wireless_32768" ( 8 )
transport/internet/tcp: dialing TCP to tcp::8443
connectex: A socket operation was attempted to an unreachable host.
Working state after disabling only Wi-Fi:
[xray] using uplink interface: "ethernet_32772" ( 11 )
No credentials, UUIDs, REALITY keys, short IDs or full live profiles are included here. Additional sanitized diagnostics can be provided if useful.
Screenshots
Not required for reproduction. Adapter/log output is more diagnostic than the UI state in this case.
Desktop (please complete the following information):
OS: Windows 10
AmneziaVPN: 5.0.1.5
Smartphone (please complete the following information):
Not applicable
Server (please complete the following information):
OS: Ubuntu 24.04.4 LTS
Native Xray server, VLESS + REALITY, TCP 8443
Additional context
The behavior appears consistent with the Windows Xray uplink-selection path in:
service/server/xray.cpp
client/core/utils/networkUtilities.cpp
Xray::startXray() obtains an interface through NetworkUtilities::getGatewayAndIface(), and the Windows socket callback later forces outbound sockets to that interface via IP_UNICAST_IF / IPV6_UNICAST_IF.
The Windows getGatewayAndIface() implementation appears to enumerate adapters with gateways and overwrite the selected result as it iterates, rather than selecting by the route to the actual Xray endpoint.
There is already an endpoint-specific route helper (AdapterIndexTo() using Windows GetBestRoute()), but it does not appear to be what determines the Xray socket-binding interface in this path.
A possible fix direction would be to resolve the uplink interface from the best route to the actual Xray server address before applying IP_UNICAST_IF.
A comparison of the directly relevant source files between 5.0.1.5 and 5.0.2.1 did not show a change to this particular adapter-selection/socket-binding path, so upgrading alone does not appear to address this specific case._______
@HeisLuka commented on GitHub (Sep 8, 2026):
I think there is a stronger invariant here than only filtering disconnected adapters.
Current dev appears to have two independent sources of truth for the XRay underlay interface.
The client routing path already does endpoint-specific selection:
const int inetAdapterIndex =
NetworkUtilities::AdapterIndexTo(QHostAddress(m_remoteAddress));
AdapterIndexTo() uses Windows GetBestRoute() and returns the interface that Windows would actually use for that destination.
That index is subsequently used by the Windows routing/WFP path through enablePeerTraffic().
But the embedded XRay service independently calls:
NetworkUtilities::getGatewayAndIface()
and stores that result as m_defaultIfaceIdx. sockCallback() then forces XRay sockets onto it using:
IP_UNICAST_IF
IPV6_UNICAST_IF
On Windows, getGatewayAndIface() does not select a route for the XRay endpoint. It enumerates adapters and overwrites resGateway/resIndex whenever it sees another IPv4 gateway.
This creates a possible split-brain:
Windows best route to XRay endpoint = ifIndex 11
enablePeerTraffic path = ifIndex 11
XRay socket IP_UNICAST_IF = ifIndex 8
which matches the reported failure very closely.
It is also enumeration-order dependent. For the same adapter state:
Ethernet ifIndex 11, active, gateway
Wi-Fi ifIndex 8, disconnected, stale gateway
current selection behaves approximately as:
enumeration [Ethernet, Wi-Fi]
-> selected XRay interface = 8
enumeration [Wi-Fi, Ethernet]
-> selected XRay interface = 11
No routing fact changed between those two cases.
I would therefore avoid fixing this only with:
if OperStatus != Up -> skip
That would remove this particular disconnected-adapter case, but the selector would still not express the actual invariant when two valid uplinks exist.
The stronger rule should be:
XRay socket underlay interface
Windows best-route interface to the actual remote XRay endpoint
interface used by routing/WFP setup
There is already code for the destination-specific part, so one possible direction is to make the decision once and reuse it.
Conceptually on Windows:
resolve remote endpoint
↓
AdapterIndexTo(remote)
↓
one immutable/session uplink index
├─> pass to xrayStart(...)
│ └─> IP_UNICAST_IF
│
└─> setupRouting()/enablePeerTraffic(...)
rather than:
setupRouting -> GetBestRoute(remote) -> interface A
xrayStart -> enumerate gateways -> interface B
xrayStart() IPC currently accepts only the config string, so passing the already selected uplink index through that boundary would also make the path identity explicit rather than recomputing it in the service.
Regression cases I would add:
Ethernet active, Wi-Fi disconnected but still has gateway metadata
best route(remote) = Ethernet
expected XRay bind = Ethernet
Both Ethernet and Wi-Fi active
best route(remote) = Wi-Fi
expected XRay bind = Wi-Fi
Same adapter facts, enumeration order reversed
expected selected uplink unchanged
Generic default gateway differs from best route to remote
expected endpoint-specific route wins
And a useful runtime assertion/log would be:
remote=
bestRouteIf=
xrayBoundIf=
routingIf=
with a warning/error if those identities diverge.
This would turn the current symptom from “XRay randomly picked Wi-Fi” into a testable path-binding invariant and should cover multi-homed systems as well as the disconnected-adapter reproduction.