mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-10-13 21:33:09 +00:00
[GH-ISSUE #3132] [macOS][XRay] Domain endpoint: utun is configured but nothing traverses the tunnel until teardown; literal IP works; iOS works #1454
Open
opened 2026-10-13 20:42:46 +00:00 by bsakaguchi
·
3 comments
No Branch/Tag specified
dev
feat/api-tests
feat/gateway-service-import-test
fix/serialize-log-record-writes-and-pin-log-date-format-locale
fix/libagw-review-fixes
feat/otp-login
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#1454
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 @konst643 on GitHub (Sep 6, 2026).
Original GitHub issue: https://github.com/amnezia-vpn/amnezia-client/issues/3132
Describe the bug
On macOS, an XRay (VLESS + Reality) profile whose server address is a domain name never establishes: the app reaches "Connected", the
utuninterface is created but never receives an IP address, no traffic flows, and networking stays broken until disconnect. On disconnect the log showsFailed to stop xray.Replacing only the server address with the server's literal IPv4 (same key, same Reality parameters, same SNI) makes the very same profile work:
utungets its address and traffic flows.To Reproduce
vpn://key (orvless://link) where the outboundvnext.addressis the domain name.ifconfigshows the newutuninterface without an inet address; nothing loads, the machine effectively loses networking until disconnect.vnext.addressset to the server's literal IPv4 — it works: theutungets its address (e.g.10.x.x.x) and traffic flows through the server.Expected behavior
A domain endpoint should work: resolve the name before the tunnel takes over the default route (or add a bypass route for the resolved IP once known). Otherwise the resolver query is routed into the tunnel that is still being established — a chicken-and-egg loop that can never complete.
Evidence that it is the resolution order
vless://link works on the same Mac in a third-party client (V2Box), which resolves the name before route setup and adds a host bypass route for the resolved address.Environment information
vpn://key with XRay JSON config (also reproduces withvless://link import)@ManguoLabsTech commented on GitHub (Sep 6, 2026):
Root cause
This is a route-before-resolve deadlock. The macOS client installs the tunnel interface as the default route before resolving the server domain name, so the DNS query itself is routed into the tunnel that cannot complete without knowing the server IP. The
utuninterface never receives an address because the xray-core process cannot reach the server to complete the handshake.Why literal IP works
When you specify a literal IPv4, no DNS lookup is needed. The client (or xray-core) can immediately install a host route for that IP via the physical interface, then safely switch the default route to the tunnel.
Why iOS works
The Network Extension framework on iOS automatically excludes the VPN provider's own traffic from the tunnel. DNS queries and the initial connection to the server go through the original network interface, avoiding the deadlock.
What needs to change
The macOS client must resolve the server domain before changing the default route, then:
route add <server-ip> <physical-gateway>)utunAlternatively, adopt the macOS Network Extension API (like iOS) so the provider's traffic bypasses the tunnel automatically.
Workarounds
Use the server's IP address in profiles
Add a static
/etc/hostsentry (if the IP is stable)Use a client that resolves before route changes
Questions for the maintainers
Does the app call
getaddrinfo/ resolve domains before starting xray-core, or does it pass the domain string directly to xray-core's config?Is the route installation done by the app or by xray-core?
Are you using a system extension, or
utunviaioctl/NEPacketTunnelProvider?Knowing the sequence (DNS → xray start → route change → IP assignment) will clarify where to inject the pre-resolution step.
@HeisLuka commented on GitHub (Sep 8, 2026):
I checked current dev, and I think it is worth separating two things here.
The existing “route-before-resolve deadlock” explanation may be directionally useful, but current code already contains some pre-resolution/underlay protection:
m_remoteAddress =
NetworkUtilities::getIPAddress(
m_rawConfig.value(configKey::hostName).toString());
so the client resolves hostName before XRay startup.
On macOS, Xray::startXray() also installs physical-interface routes before amnezia_xray_start(), and XRay sockets are bound using:
IP_BOUND_IF
IPV6_BOUND_IF
Therefore I would not yet treat “the DNS query is definitely sent into the unfinished tunnel” as proven without observing the actual XRay DNS socket/path.
There is, however, a deterministic false-success path in the macOS TUN setup that seems directly relevant to:
UI says Connected
but utun has no inet address
RouterMac::createTun() currently runs:
ifconfig inet up
and checks only whether QProcess started and finished.
It does not check:
process.exitStatus()
process.exitCode()
stderr
so a failed ifconfig command can still return true.
XrayProtocol::setupRouting() then treats that as:
TUN address successfully assigned
and after setupRouting() returns NoError, the connection is promoted to:
Vpn::ConnectionState::Connected
I would add a regression test for this independently of the DNS root cause:
make macOS ifconfig return non-zero
expected:
createTun() == false
setupRouting() fails
connection never reaches Connected
forbidden:
command finished != address configured successfully
Minimal correctness fix:
if (!process.waitForFinished(...))
return false;
if (process.exitStatus() != QProcess::NormalExit ||
process.exitCode() != 0) {
qCritical() << process.readAllStandardError();
return false;
}
Even stronger would be a postcondition/read-back:
expected inet address is actually present on utun
before reporting routing setup success.
For the domain-vs-IP difference, I would then run one controlled A/B rather than infer DNS from the symptom:
A. current runtime config:
vnext.address = vpn.example.com
B. resolve vpn.example.com before startup,
use the resolved IP only as runtime vnext.address,
keep REALITY serverName/SNI unchanged
If B works while A consistently fails, that specifically isolates the second name-resolution inside XRay.
This matters because current client-side pre-resolution stores the result in m_remoteAddress, but the runtime XRay JSON is still passed to the service as xrayConfigStr; on macOS that pre-resolved address is not currently used the same way it is in the Windows routing path.
Useful logging for the same run would be:
original hostname
client pre-resolved A/AAAA
physical uplink iface/gateway
routeAddXray result
XRay actual dial target / DNS result
ifconfig exit code + stderr
utun expected address read-back
connection state transition
That should distinguish:
PRE_FLOW_DNS
vs
XRay transport failure
vs
TUN configuration false-success
instead of grouping all three under “domain endpoint fails”.
@konst643 commented on GitHub (Sep 13, 2026):
Ran the controlled A/B you asked for, with capture on the server side as well. B works, A fails — and the tunnel interface gets its address in both arms, so the title of this issue is wrong: the
utunis configured correctly, it just carries nothing.Setup: macOS, AmneziaVPN 5.0.2.0, XRay VLESS + REALITY on my own server. Same profile in both arms; in B only
vnext.addressis replaced by the resolved IPv4, REALITYserverNameleft untouched.A —
vnext.address = edge.example.oneConnected~300 ms afterXrayProtocol::start()utun22receives10.33.0.2, MTU 1500 — the read-back you suggested would passdig @1.1.1.1 example.comtimes out over UDP and over TCP;scutil --dnsshows 1.1.1.1 / 1.0.0.1 scoped to the tunnelB —
vnext.address = <resolved IPv4>, same key, same SNIhttps://example.orgreturns 200 in 0.5 s; 3 MB download in 1.4 sRouting is identical in both arms, so the data path is not what differs:
Two things there look wrong independently of this issue: there is no
/32exclusion for the server address in either arm, and the split halves are inconsistent —0/1points at the physical interface while128.0/1is installed twice, once per interface. Traffic in B flows regardless because the service's own sockets are bound to the uplink: one attempt shows 184 outbound connections fromAmneziaVPN-serviceto port 443 overen0. SoIP_BOUND_IFis doing the work the route table is not.That lines up with what you predicted. Client-side pre-resolution into
m_remoteAddressdoes happen, but the runtime JSON still carries the name, and XRay's own resolution of it is not bound to the uplink the way its dialer is. With the tunnel's scoped resolvers already installed and nothing traversing the tunnel, that query cannot complete — and it completes the instant the routes are removed, which is exactly when the burst arrives. By your taxonomy this is the second case, name resolution inside XRay, notPRE_FLOW_DNSand not TUN false-success.Happy to re-run with any additional logging you want to add, or to retitle this issue to describe the actual symptom.