Skip to main content
RunBook Academy

← All break/fix scenarios in VyOS

advancedvyos-multiawan~30 min

Multi-WAN Failover Does Not Occur

Reported symptoms

  • From 08:40 the office reports no Internet access from any LAN host. Internal systems and anything on the LAN are unaffected.
  • The NOC dashboard shows both WAN circuits green and has shown them green throughout. Its check is an SNMP poll of interface operational status.
  • show bfd peers reports the session to the primary ISP next hop Up, with 41 days of uptime and no flaps recorded.
  • The router itself cannot reach the Internet either. This is the symptom that rules out an entire family of causes and is usually the last one anybody tests.
  • The site-to-site IPsec tunnel to the DR site went down at 08:12 and has not returned. The DR team has opened a separate ticket describing it as IPsec instability.
  • The external monitor for the published web service went red at 08:12, twenty-eight minutes before the first user call, and was routed to the web team as an application alert.
  • show ip route 0.0.0.0/0 shows the primary default route selected and the backup default route present at distance 200 and not installed. Failover has not fired.
  • The failover was tested successfully six weeks ago and the measured time, 210 ms, is written in the change record.

Evidence

  • · show interfaces ethernet eth0 shows the link up, no errors, and zero carrier transitions since boot. Physically nothing has happened on this router.
  • · ping 203.0.113.1 interface eth0 returns 0% loss. The primary ISP next hop is alive and answering.
  • · traceroute to any Internet destination shows hop 1 as 203.0.113.1 and nothing after it. The path ends one hop beyond the router.
  • · ping 198.51.100.1 interface eth1 returns 0% loss, and a target beyond that next hop also answers when the ping is pinned to eth1. The backup circuit is carrying traffic to the Internet right now.
  • · show ip route 0.0.0.0/0 lists S>* 0.0.0.0/0 [1/0] via 203.0.113.1, eth0 and S 0.0.0.0/0 [200/0] via 198.51.100.1, eth1 inactive.
  • · show configuration commands | match "static route 0.0.0.0/0" shows the two routes, the distance 200 on the backup, and bfd on the primary next hop. There is nothing else.
  • · show configuration commands | match load-balancing returns nothing. There is no health check on this router beyond BFD.
  • · show bfd peers shows the session to 203.0.113.1 Up, uptime 41 days, diagnostic ok.
  • · The change record for the failover test six weeks ago records the method as set interfaces ethernet eth0 disable, followed by commit.
  • · The ISP confirms a fault in their aggregation layer, upstream of the customer handoff, with no restoration estimate.
Diagnosis and resolutionclick to reveal

Root cause

Nothing on this router can see the failure that occurred, so nothing withdrew the primary route, so the backup route was never installed. Administrative distance is a tie-break applied when a route is installed, not a health check: FRR selects the lowest-distance route whose next hop resolves, and the distance-200 backup becomes eligible only when the distance-1 primary is withdrawn. Withdrawal requires a detector, and both detectors this estate owns describe the wrong thing. Interface state describes the Ethernet segment between eth0 and the ISP demarcation equipment, which is intact and will stay intact through almost any fault beyond it. BFD describes the liveness of the next hop itself, which is the ISP handoff router - a device that is running normally and answering everything asked of it. The fault is in the ISP aggregation layer behind that router, so the last honest statement either detector can make is that the first hop is healthy, and it is. The six-week-old drill measured 210 ms of failover for the one failure mode link tracking already covered, disabling the interface, and its success is what retired the question. What is left is a router forwarding every packet into a path that ends one hop away, with a healthy backup circuit sitting beside it and no mechanism that will ever choose it.

Remediation

Fail over by hand, from the console or an out-of-band session, because the in-band management path runs over the circuit that is dead. The minimal change is to withdraw the primary rather than to reorder anything: set protocols static route 0.0.0.0/0 next-hop 203.0.113.1 disable keeps the route in the configuration, removes it from FRR, and lets the distance-200 backup install. Apply it with commit-confirm only if someone is present to confirm, because the timer will hand the estate back to the dead circuit at expiry. Then understand what failing over does not restore, and tell the owners before they discover it: outbound traffic now leaves with the backup circuit's source address, so any partner filtering on the primary address refuses it; the DR IPsec tunnel is pinned to the primary WAN address by its local-address and does not come back until that is changed at both ends; every service published by destination NAT on the primary address stays unreachable, because inbound traffic returns to the address the far end was told about; and the backup is a fraction of the primary's capacity, so the estate is degraded rather than restored. Established flows translated to the dead address will not recover on their own - clear them with a filter that names the address, after listing the same filter first, rather than with a table flush that drops every tracked flow on the router. Hold is a legitimate decision when the ISP has a short restoration estimate: a failover that breaks tunnels and allowlists can cost more than the outage it answers. Record the hold with an owner, an end time and the point at which it is revisited.

Verification

Verify the promotion in the routing table and then verify the traffic, because the routing table was not the thing that failed. show ip route 0.0.0.0/0 must show the backup route selected and installed with the primary absent. Then confirm a LAN host reaches the Internet, that its flow leaves by eth1, and that the source address observed at a remote endpoint is the backup circuit's address - show conntrack table ipv4 and monitor interface eth1 both settle this, and neither is inferable from the route. Re-test the flows that were named as casualties rather than assuming them: the DR tunnel, the published services, and anything with a source-address allowlist. When the primary circuit is restored, do not remove the disable in the same breath as the ISP reports it fixed; prove the path first with ping 203.0.113.1 interface eth0 and a target beyond it pinned to eth0, then re-enable, then confirm the primary reselects and traffic follows it. The last verification is the one that closes the incident rather than the outage: a detector that would have seen this fault, demonstrated seeing it, by blackholing traffic beyond the handoff while the link stays up.

Prevention

Add a detector whose statement is about the path rather than about the first hop. A ping test to a target beyond the ISP next hop, pinned to the interface being monitored and requiring several consecutive failures, is the only mechanism in the table that sees an ISP whose own upstream has failed; VyOS provides it through load-balancing wan interface-health, and the WAN failover runbook covers the build and its blast radius. Use two targets in different networks so one distant outage is not read as your circuit failing. Keep BFD as well rather than instead: it detects a handoff router that dies or stops forwarding, far faster than any probe, and it is blind to exactly this fault. Drill the failure you fear, not the failure that is easy to stage. Disabling an interface tests link tracking and nothing else; blackholing traffic beyond the handoff while carrier stays up reproduces the grey failure that actually happens, and it is the only drill that would have failed six weeks ago. Wire the alerts to the estate rather than to teams: an external monitor for a published service going red is a statement about the WAN, and twenty-eight minutes of it being read as a web-application alert is the difference between a detected outage and a reported one. Finally, write down what failover does not cover - inbound published services, address-pinned tunnels, partner allowlists - in the change record, because the people who need that list are the ones who will be told the failover worked.

Reported symptoms

edge-rtr-01 is a VyOS 1.5 LTS router with two circuits. eth0 is the primary, 203.0.113.2/30 with next hop 203.0.113.1, handed off on fibre through the ISP’s own equipment in the comms room. eth1 is the backup, 198.51.100.2/30 with next hop 198.51.100.1, a much smaller circuit from a second provider. eth2 is the LAN, 10.40.0.0/16.

Failover is the ordinary design: two static default routes, the backup carrying distance 200, with BFD on the primary next hop because this ISP answers it. It was tested six weeks ago and the measured failover time, 210 ms, is in the change record.

  • 08:12, the DR team. The site-to-site IPsec tunnel to the DR site has dropped and is not re-establishing. They open a ticket about IPsec instability.
  • 08:12, the external monitor. The published web service goes red. The alert routes to the web team, who find their servers healthy and begin looking at the application.
  • 08:40, the office. No Internet from any LAN host. Internal systems are unaffected, so the first theory is DNS.
  • Throughout, the NOC dashboard. Both circuits green. The check is an SNMP poll of interface operational status, and it is telling the truth about what it measures.

Three tickets, three teams, one cause, and twenty-eight minutes between the first alert and anyone connecting them.

Evidence provided

The router’s own view of the circuits contradicts the users’ view of the estate, which is the fastest way into this fault:

Read-only / Safethe backup is present and has never been chosen
$ show ip route 0.0.0.0/0
Codes: K - kernel route, C - connected, S - static, B - BGP,
     > - selected route, * - FIB route

S>* 0.0.0.0/0 [1/0] via 203.0.113.1, eth0, weight 1, 06w1d02h
S   0.0.0.0/0 [200/0] via 198.51.100.1, eth1 inactive, weight 1, 06w1d02h

Illustrative output

Read-only / Safe41 days, no flaps
$ show bfd peers
peer 203.0.113.1 vrf default interface eth0
ID: 1938271645
Remote ID: 2044817263
Status: up
Uptime: 41 day(s), 3 hour(s), 12 minute(s)
Diagnostics: ok
Remote diagnostics: ok

Illustrative output

The link is up with zero carrier transitions since boot, and the primary next hop answers:

vyos@edge-rtr-01:~$ ping 203.0.113.1 interface eth0 count 5
PING 203.0.113.1 (203.0.113.1) from 203.0.113.2 eth0: 56(84) bytes of data.
64 bytes from 203.0.113.1: icmp_seq=1 ttl=64 time=0.71 ms
64 bytes from 203.0.113.1: icmp_seq=2 ttl=64 time=0.68 ms
64 bytes from 203.0.113.1: icmp_seq=3 ttl=64 time=0.74 ms
64 bytes from 203.0.113.1: icmp_seq=4 ttl=64 time=0.66 ms
64 bytes from 203.0.113.1: icmp_seq=5 ttl=64 time=0.70 ms

--- 203.0.113.1 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4082ms

A traceroute from the router toward any Internet destination reaches 203.0.113.1 and then nothing: every subsequent hop is a row of asterisks. The same test pinned to the backup interface is entirely healthy — ping 198.51.100.1 interface eth1 answers, and so does a target well beyond that next hop when the ping is pinned to eth1.

The failover configuration is three lines and has not changed:

show configuration commands | match "static route 0.0.0.0/0"

set protocols static route 0.0.0.0/0 next-hop 203.0.113.1 bfd
set protocols static route 0.0.0.0/0 next-hop 198.51.100.1 distance '200'
set protocols static route 0.0.0.0/0 next-hop 198.51.100.1 interface 'eth1'

show configuration commands | match load-balancing returns nothing. The ISP, when called, confirms a fault in their aggregation layer, upstream of the customer handoff, with no restoration estimate.

Work the evidence before reading on

The backup circuit is healthy and carrying test traffic while you read this. The router has decided not to use it.

  1. Write down what each detector on this router actually measures. Interface state measures a property of which cable? BFD measures a property of which device? Then locate the fault relative to both.
  2. show ip route 0.0.0.0/0 shows the backup at distance 200 and inactive. Under what precise condition does FRR install it, and has that condition been met?
  3. The router itself cannot reach the Internet. Which family of causes does that single fact eliminate, and how much time does eliminating it save?
  4. The drill six weeks ago failed over in 210 ms. What did it test, and is that the same thing as what happened this morning?
  5. Three tickets arrived from three teams. What is the common cause, and which of the three arrived first?

Before continuing: state the condition that must become true before the backup route can install, and name every mechanism on this router capable of making it true.

Root cause

1. Administrative distance is a tie-break, not a health check

FRR installs the lowest-distance route whose next hop resolves. Two default routes at distances 1 and 200 mean exactly one thing: while both are eligible, the distance-1 route wins. The distance-200 route becomes eligible only when the distance-1 route stops existing.

Nothing in this configuration ever makes it stop existing. The next hop 203.0.113.1 resolves — it is on a connected subnet of an interface that is up, and it answers ARP — so the route stays installed and the backup stays inactive. This is not a failure of the routing table. The routing table is doing precisely what a routing table does, and it has no opinion about whether packets sent to 203.0.113.1 reach anything afterwards.

2. Both detectors are true statements about the wrong subject

Interface state is a statement about the Ethernet segment between eth0 and the ISP’s demarcation equipment. That segment is fine, and on a handoff through a media converter, an ONT or a switch it stays fine through almost any fault beyond it. Zero carrier transitions since boot is the evidence: nothing physical happened on this router.

BFD is a statement about the liveness of 203.0.113.1 itself. That device is running normally, forwarding BFD control packets on schedule, and answering ICMP with sub-millisecond latency. Forty-one days of uptime and no flaps is not BFD failing to do its job; it is BFD correctly reporting that the peer it was pointed at is alive.

The fault is in the ISP’s aggregation layer behind that router. Both detectors stop measuring one hop short of it. There is no configuration error here to find, which is why the first hour is spent looking for one.

3. The drill validated the failure mode that was already covered

Six weeks ago the test was set interfaces ethernet eth0 disable followed by commit. That removes the interface, removes the connected route, makes the next hop unresolvable and withdraws the primary — so the backup installs, in 210 ms, exactly as recorded.

It is a real test of one failure mode: carrier loss. It is the failure mode interface state already catches, and it says nothing about the mode where the circuit is electrically perfect and forwards nothing. The drill passed, the question was retired, and the estate carried a failover design that could only respond to the cheapest failure for six more weeks.

Resolution

  1. Get to a console or an out-of-band session before touching anything. The in-band management path runs over the circuit that is dead, and every step below assumes you are not on it.
  2. Confirm the backup circuit carries traffic before you depend on it: ping 198.51.100.1 interface eth1, then a target beyond that next hop pinned to eth1. A backup nobody has tested this morning is a hypothesis.
  3. Decide between failing over and holding, and record the decision. If the ISP has a short restoration estimate and the backup cannot carry the load, holding may cost less than a failover that breaks tunnels and allowlists. A hold needs an owner, an end time and a stated point at which it is revisited; without those it is not a decision.
  4. Tell the owners of the flows that will break before the change, not after: anything with a source-address allowlist at the far end, the DR IPsec tunnel pinned to the primary WAN address by its local-address, and every service published by destination NAT on the primary address.
  5. Withdraw the primary rather than reordering the pair: set protocols static route 0.0.0.0/0 next-hop 203.0.113.1 disable. The route stays in the configuration and stops being rendered to FRR, which is the smallest change that lets the backup install.
  6. Use commit-confirm only if someone is present to confirm within the window. The timer restores the dead circuit at expiry, which is correct behaviour for a mistake and wrong behaviour for an unattended outage.
  7. Confirm the promotion in show ip route 0.0.0.0/0 and then in the data plane. A LAN host reaching the Internet is the check; the routing table is only the reason it should work.
  8. Clear the flows that were translated to the dead address, listing before deleting and naming the address in the filter. Do not flush the whole table: every tracked flow on the router goes with it, including the ones on the healthy circuit.
  9. When the ISP reports restoration, prove the path yourself before reverting: ping 203.0.113.1 interface eth0 and a target beyond it pinned to eth0. Then delete the disable, commit, and watch the primary reselect.
  10. save, and put the measured numbers in the ticket: when the fault started, when it was detected, when it was detected as a WAN fault, and how long the manual failover took.

Verification

  1. The backup is installed, not merely eligible. show ip route 0.0.0.0/0 shows the backup route selected with the primary gone, rather than present and inactive.
  2. A LAN host reaches the Internet. This is the assertion the whole change exists to make true, and it is not implied by the routing table.
  3. Traffic actually leaves eth1 and is translated on the way out. show conntrack table ipv4 and monitor interface eth1 show the flows; a backup path that routes correctly and translates nothing is the next incident, and it has its own scenario in this course.
  4. The remote end sees the backup circuit as the source address. Confirming this from outside the estate is what turns a routing change into a working path.
  5. The named casualties were re-tested rather than assumed: the DR tunnel, the published services, and the partner flows with source-address allowlists. Each is either restored or explicitly recorded as still down and owned.
  6. On restoration, the primary was proved before it was trusted - next hop and a target beyond it, both pinned to eth0 - and only then re-enabled.
  7. The detector that would have caught this fault exists and has been demonstrated catching it. Blackhole traffic beyond the handoff while carrier stays up and watch the route withdraw; a detector that has only ever reported up has not been tested.

Prevention

  • Probe beyond the failure domain. A test to a target on the far side of the ISP, pinned to the monitored interface and requiring several consecutive failures, is the only detector that sees an ISP whose own upstream has failed. Two targets in different networks keep one distant outage from being read as your circuit failing.
  • Keep BFD as well. It sees a handoff router that dies or stops forwarding, in milliseconds, and it is blind to this fault. The two detectors answer different questions and neither substitutes.
  • Drill the failure you fear. Disabling the interface tests link tracking. Blackholing traffic beyond the handoff, with carrier up, reproduces the grey failure and is the only drill that would have failed six weeks ago.
  • Read the first alert as an estate alert. The published service went red twenty-eight minutes before the first user call. Routing that alert to the application team, rather than treating an external reachability failure as a statement about the WAN, is where the outage got its length.
  • Write down what failover does not cover. Inbound published services, tunnels pinned to a WAN address, and partner allowlists do not move with the default route. The people who need that list are the ones who will be told the failover worked.
  • Test the backup circuit on a schedule, not on the day. A circuit that has carried nothing since installation is an assumption with a monthly invoice attached.