The short answer
NetworkManager gives every connection a route metric, and the lowest one carries your traffic. Ethernet normally gets 100 and Wi-Fi 600, so Ethernet wins while its link is up. You can change the numbers with nmcli. NetworkManager's connectivity check, when it's on, can also push a connection without internet down the list, but it checks only every few minutes and only asks "internet or not".
How Ubuntu picks a connection
Ubuntu sends traffic through the default route with the lowest metric, and Ethernet (100) normally beats Wi-Fi (600). To see the default routes:
ip route show defaultWith both connected you see two lines, something like this (your device names and addresses will differ):
default via 192.168.1.1 dev enp3s0 proto dhcp src 192.168.1.20 metric 100
default via 192.168.1.1 dev wlp2s0 proto dhcp src 192.168.1.21 metric 600The route with the lower metric is used. enp3s0 is the Ethernet device here and wlp2s0 the Wi-Fi. To list your devices and connection names:
nmcli device status
nmcli connection show --activeIf the Ethernet cable is unplugged, its route goes away and Wi-Fi takes over at once. If the cable stays connected but the router or provider has stopped working, the Ethernet route stays, and with it the lower metric.
Prefer Wi-Fi for now
Give the Wi-Fi device a lower route metric than the Ethernet one with nmcli device modify. Traffic moves at once, and your saved settings stay as they are. Use your own device name:
nmcli device modify wlp2s0 ipv4.route-metric 90This changes only the running device, IPv4 only. Nothing disconnects. To undo it, re-apply the saved profile (a reboot also undoes it):
nmcli device reapply wlp2s0Keep the number above 50 if you use a VPN, since NetworkManager commonly gives VPN routes a metric of 50.
Change the order for good
To make one connection always preferred, set the metric in its saved profile and reconnect it. For example, to always prefer Ethernet with a fixed value:
nmcli connection modify "Wired connection 1" ipv4.route-metric 100 ipv6.route-metric 100
nmcli connection modify "MyWiFi" ipv4.route-metric 600 ipv6.route-metric 600
nmcli connection up "Wired connection 1"
nmcli connection up "MyWiFi"Use the names from nmcli connection show. A value of -1 returns a profile to the default. This is a fixed order: it still won't react when the preferred connection loses its internet.
NetworkManager's connectivity check
It is a slow, basic failover: when the check is on and a device fails it, that device drops down the list. NetworkManager tests whether each device really reaches the internet by fetching a small web page. On Ubuntu desktop this is usually set up by a configuration file pointing at connectivity-check.ubuntu.com, and it can be switched off in Settings under privacy.
To move a failing device down the list, NetworkManager can add a large penalty (20000) to that device's default-route metric. The other device then has the lower number and takes your traffic: a built-in failover of sorts. To see what your system does:
# is the check turned on? (prints "b true" or "b false")
busctl get-property org.freedesktop.NetworkManager \
/org/freedesktop/NetworkManager \
org.freedesktop.NetworkManager ConnectivityCheckEnabled
# the result for each device: full, limited, portal, none or unknown
nmcli -f DEVICE,IP4-CONNECTIVITY device status
# where it is configured, and how often it runs
grep -r -A4 "\[connectivity\]" /etc/NetworkManager /usr/lib/NetworkManager 2>/dev/nullIts limits for this job:
- It is slow. Unless the configuration sets an
interval, it checks every 300 seconds, so an outage can last minutes before anything changes. - It is one request. A single HTTP fetch to one address, from one place.
- It is yes or no. A connection with heavy packet loss or very high latency still counts as working.
- It is quiet. Nothing on screen tells you which connection is carrying your traffic or why it changed.
If you want to rely on it, you can lower the interval in a file under /etc/NetworkManager/conf.d/ and restart NetworkManager. Test it by unplugging your router's internet cable rather than the computer's, since that is the case that matters.
Scripts
A script can do failover, but you write and maintain the logic yourself. A common answer on Ask Ubuntu is a NetworkManager dispatcher script in /etc/NetworkManager/dispatcher.d/, or a timer that pings and changes metrics. The logic has to ping through each device separately (ping -I enp3s0 ...), avoid switching back and forth on a single lost packet, and restore the original metrics afterwards.
Do it automatically
LAN Wi-Fi Manager tests both devices and changes the Wi-Fi route metric for you, then changes it back, with a window you can look at:
- Every 30 seconds by default it pings the internet through the Ethernet device and through the Wi-Fi device separately, and checks DNS on each.
- After 2 bad Ethernet checks it lowers the Wi-Fi device's route metric just below the Ethernet one with
nmcli device modify, the temporary change shown above. Only the Wi-Fi device's IPv4 metric is changed (IPv6 is left alone, so on a dual-stack network IPv6 traffic can stay on Ethernet), and it stays above the VPN range. - It works alongside the connectivity check: it compares metrics without the check's penalty, and it won't move you to a Wi-Fi that NetworkManager reports has no internet.
- After 2 good Ethernet checks it moves back. No password is needed: NetworkManager allows the change for the signed-in user.
- A route map shows which line is carrying traffic and every switch, with latency, loss, jitter and DNS for both.
LAN Wi-Fi Manager for Ubuntu
Free, closed source, no account. Install with sudo apt install ./LanWifiManager_2.3.0_amd64.deb from the download folder.