Dual-WAN failover that actually fails over
The fiber drops. You pay for a second circuit precisely so this doesn't matter — LTE, cable, fixed wireless, whatever it is — and it's supposed to pick up. Twenty minutes later the card reader is still spinning, the phones are still dead, and someone is asking you what exactly the backup line is for.
Then it comes back on its own, and you never find out what happened.
Failover is one of those features that looks configured and isn't. Writing the config takes ten minutes. Deciding what the router should watch is the whole job.
Link state is the wrong signal
The basic setup is two default routes at different distances:
/ip route
add dst-address=0.0.0.0/0 gateway=203.0.113.1 distance=1
add dst-address=0.0.0.0/0 gateway=198.51.100.1 distance=2
The backup route activates when the primary goes inactive, and by default the primary only goes inactive when its interface loses link — the cable came out, or the port died.
That is a real failure mode. It is also the rarest one. Nearly every outage you will actually live through happens upstream of the box on your wall: a fiber cut two towns over, a failed aggregation router, a change window that went badly at the ISP. The modem still shows a link light. Your ethernet port still has carrier. The route stays installed, and every packet you send falls into a hole.
Pinging the gateway is better, and still wrong
The obvious improvement is check-gateway=ping, which makes the router probe the gateway address and pull the route when it stops answering.
Look closely at what it's probing. 203.0.113.1 is the ISP's router at the far end of your access circuit — physically close to you, and usually the last thing in the chain to break. It will answer your pings cheerfully while its own upstream is gone. You have added a health check that passes during exactly the outage you built it for.
Probe the path, not the hop
What you want to know is whether you can still reach the internet through this circuit. RouterOS expresses that as a recursive route — a default route whose next hop is an address that can only be resolved through one specific WAN:
/ip route
add dst-address=9.9.9.9/32 gateway=203.0.113.1 scope=10 check-gateway=ping
add dst-address=0.0.0.0/0 gateway=9.9.9.9 target-scope=11 distance=1
add dst-address=0.0.0.0/0 gateway=198.51.100.1 distance=2
Read it from the bottom. The primary default route's next hop is 9.9.9.9, and it will only resolve that address through a route whose scope is 11 or lower. The only such route is the /32 pinned to the primary WAN's gateway, and that /32 carries check-gateway=ping — so the router is now pinging a host out on the public internet, forced down the primary circuit. When those pings stop, the /32 goes inactive, the default route can no longer resolve its next hop, and the distance-2 route takes over.
Two rules about probe targets. Give each WAN a different one; if both circuits check the same address and that address goes down for maintenance, you have engineered a way to lose both at once. And keep the /32's scope low, so the probe can never leak out over the other WAN and report a primary that isn't there.
The part that gets skipped: your sessions don't come with you
Here is what the config guides leave out. Failing over changes your public IP address. Every translated session on the old circuit is now invalid — not slow, invalid. The phones' SIP registrations. The site-to-site tunnel. The card terminal's connection to the processor. The long-lived connection your line-of-business app holds open to a hosted database. All dead at the same instant, all needing to notice and rebuild themselves.
So "the route switched in four seconds" is not the number that matters. The number that matters is how long until the business works again, and that is governed by application timers, not by your router. Phones on a five-minute re-registration interval take five minutes. A tunnel with a lazy dead-peer-detection setting takes as long as that setting says.
Which means most of the real design work sits on the far side of the router. Give anything that must survive a hostname instead of an IP address, keep dynamic DNS updated for both WANs rather than just the primary, and shorten keepalives on your tunnels. WireGuard behaves well here because it has no session to lose — a peer set to persistent-keepalive=25s re-establishes in roughly that long, from whatever address it now has, with no reconnect logic involved.
What to do
- Replace bare link-state failover with a recursive route check per WAN, each using its own public probe target.
- Confirm NAT masquerades on both WANs, not just the primary. A failover that routes correctly and doesn't translate is still an outage.
- Test it honestly. Unplugging the WAN cable tests the one failure mode that already worked. Blackhole your probe target instead, or have the ISP drop the circuit at their end.
- Time recovery with a stopwatch, from the failure to the moment a phone call actually connects — not to the moment the graph twitches.
- Decide what failback should do. When the primary returns, everything you just rebuilt gets torn down again. On a circuit that flaps, staying on the backup is the better answer.
Two circuits and no real confidence they'd hand off? NetCare covers the failover design and the monitoring that proves it works.
Need this kind of thinking applied to your own setup? Get in touch →