VyOSXXXI · BGP TroubleshootingTroubleshooting
BGP routes missing — not received, not advertised, not installed
What you'll learn
- Distinguish the three failure points — not received, not advertised, not installed
- Walk the BGP RIB from received-routes through Adj-RIBs-In to Loc-RIB to FIB
- Identify the configuration that drops a route at each stage
- Read show ip bgp, show ip bgp neighbors <ip> received-routes, and show ip route for the evidence
- Recognise the production failure modes — peer filter, route-map, network missing, next-hop unreachable, rib-failure
Prerequisites
Verified against VyOS 1.5.x LTS (circinus) · VyOS 1.4.x (sagitta) — legacy · FRRouting 10.x (VyOS 1.5) · Linux kernel 6.6 LTS (VyOS 1.5 base) · strongSwan 5.9.x (IPsec) · WireGuard 1.0.x (kernel module + userspace tooling) · 2026-08-15
A missing BGP route on VyOS 1.5 LTS has exactly three failure points: the route was not received from the peer, the route was received but not selected into the Loc-RIB, or the route was selected but not installed in the kernel FIB. Each failure point has a different evidence trail, a different VyOS configuration idiom to check, and a different fix. The operator who can localise the failure to one of the three stages finds the cause in minutes; the operator who cannot spends hours guessing.
This lesson walks the BGP RIB from peer to kernel, names the configuration that drops a route at each stage, and shows the operational evidence that distinguishes the three failure points. The goal is the ability to look at a missing route and immediately say “this is a not-installed failure — next-hop is unreachable” without running every BGP command.
The three failure points and their evidence
flowchart LR
P1[Peer Router] -->|UPDATE message| R1
R1{Received from peer?} -->|yes| R2
R1 -->|no| FAIL1[FAILURE 1: not received<br/>session down, peer filter, attribute rejected]
R2{Selected into Loc-RIB?} -->|yes| R3
R2 -->|no| FAIL2[FAILURE 2: not selected<br/>best-path algorithm rejected it]
R3{Installed in FIB?} -->|yes| OK[Route is live]
R3 -->|no| FAIL3[FAILURE 3: not installed<br/>next-hop unreachable, rib-failure]
subgraph "FRR BGP daemon"
R1
R2
R3
end
FAIL1 -.-> EV1["Evidence: show ip bgp neighbors <ip> received-routes"]
FAIL2 -.-> EV2["Evidence: show ip bgp <prefix> shows d > instead of d *"]
FAIL3 -.-> EV3["Evidence: show ip bgp <prefix> shows *> but show ip route <prefix> shows nothing"]
The diagram shows the three failure points and the evidence the operator uses to localise the failure. The three checks (received-routes, show ip bgp <prefix>, show ip route <prefix>) are the three commands the operator runs in order.
The Adj-RIBs-In, Loc-RIB, and FIB walk
The BGP process has three internal tables that matter for the operator:
- Adj-RIBs-In — every route received from every peer, before any filter or best-path decision. This is the raw inbound stream. The operator accesses this with
show ip bgp neighbors <ip> received-routes. - Loc-RIB — the routes that survived inbound filtering and best-path selection. This is the BGP table from the local router’s perspective. The operator accesses this with
show ip bgporshow ip bgp <prefix>. - Adj-RIBs-Out — the routes advertised to each peer, after outbound filtering. The operator accesses this with
show ip bgp neighbors <ip> advertised-routes. - FIB — the kernel forwarding table. The operator accesses this with
show ip route.
The walk for a missing route is:
- Is the route in Adj-RIBs-In? Run
show ip bgp neighbors <ip> received-routes. If not, the route was not received. Stop here. - Is the route in Loc-RIB? Run
show ip bgp <prefix>. If not, the route was received but not selected. Look at the flags:dmeans dampened,hmeans history (received but unreachable),>means best,*means valid. - Is the route in the FIB? Run
show ip route <prefix>. If not, the route was selected but not installed. Look for*>inshow ip bgp <prefix>— the route is best and valid — but absence fromshow ip routemeans the kernel refused it.
The three commands are the operator’s diagnostic triangle. Every missing-route diagnosis starts here.
Failure point 1 — not received
The route was never added to Adj-RIBs-In. The most common causes:
- The BGP session is not in Established. A session in Idle, Connect, Active, OpenSent, or OpenConfirm does not exchange UPDATEs. Check
show ip bgp summaryfirst. - The peer did not advertise the route. The route may not exist on the peer’s Loc-RIB. Check the peer’s
show ip bgp <prefix>directly or via the NOC. - The inbound prefix-list, filter-list, or route-map rejected the route. The route arrived on the wire but the inbound filter dropped it before Adj-RIBs-In. The evidence is in
show ip bgp neighbors <ip> received-routes(which bypasses the inbound filter) versus the absence inshow ip bgp <prefix>.
The operator who sees the route in received-routes but not in show ip bgp is at failure point 2. The operator who does not see the route in received-routes is at failure point 1.
Diagnosis for failure point 1
show ip bgp summary
show ip bgp neighbors <ip> received-routes
show ip bgp regexp <as-path-regex>
show configuration commands | match prefix-list
show configuration commands | match route-map
The first command shows the session state. The second shows the raw inbound stream. The third shows the routes that match a particular AS path. The fourth and fifth show the filter configuration the operator can correlate against the missing route.
The canonical production error: the operator configures an inbound prefix-list that is too restrictive. A common mistake is permit 10.0.0.0/8 le 32 (accept all of 10.0.0.0/8) when the intent was to accept the entire RFC1918 range. The fix is to add permit 172.16.0.0/12 le 32 and permit 192.168.0.0/16 le 32 to the prefix-list, or to use a more permissive rule.
Failure point 2 — received but not selected
The route is in Adj-RIBs-In but not in Loc-RIB. The most common causes:
- The route is in
historystate. The route was received but its NEXT_HOP is not reachable. BGP marks ith(history) instead of*(valid). The fix is to make the NEXT_HOP reachable (e.g., advertise the NEXT_HOP via IGP, or usenext-hop-self). - The route is
d(dampened). Route flap damping has suppressed the route. The fix is to disable damping, wait for the penalty to decay, orclear ip bgp dampening <prefix>. - The route is
r(RPKI invalid). RPKI validation has marked the route as invalid. The fix is to correct the ROA, or to disable RPKI for the prefix. - The route lost the best-path decision to another route from the same or different peer. The eleven-step algorithm picked a different path. The losing route is in Adj-RIBs-In but not in Loc-RIB as
best.
The operator who sees h in show ip bgp <prefix> knows the route has a NEXT_HOP problem. The operator who sees d knows damping is in play. The operator who sees multiple paths with no > knows the algorithm picked one and the others are not best.
Diagnosis for failure point 2
show ip bgp <prefix>
show ip bgp neighbors <ip> received-routes
show ip bgp regexp <as-path-regex>
show ip bgp <prefix> bestpath
show ip route <next-hop>
The first command shows all candidate paths for the prefix and their flags. The second shows the raw inbound stream for comparison. The third is the AS-path-filtered view. The fourth is the best-path walk for the prefix. The fifth confirms the NEXT_HOP is reachable in the IGP.
The canonical production error: the operator configured an inbound route-map that sets a community or weight and the route is filtered out by the route-map’s match clauses. The fix is to walk the route-map’s match clauses in order and confirm which one is excluding the route.
Failure point 3 — selected but not installed
The route is *> in show ip bgp <prefix> (valid and best) but is not in show ip route <prefix>. The most common causes:
- The NEXT_HOP is not in the FIB. The route’s NEXT_HOP is reachable via the IGP (Adj-RIBs-In marked it valid), but the kernel FIB does not have a route to the NEXT_HOP. This is the classic “BGP says valid but kernel says unreachable” — usually caused by a stale IGP route, a recursive routing loop, or a missing static route.
- The
bgp table-mapfiltered the route out of the Loc-RIB-to-FIB handoff. The table-map applies a route-map to every route going into the FIB. If the route-map denies the route, BGP does not install it. - The route is in a VRF the operator did not expect. The operator runs
show ip route(default VRF) but the route is inshow ip route vrf <name>. - The route is
rib-failure. FRR has a special flag for routes that are in Loc-RIB but not in FIB because the kernel rejected them. The flag appears asr>inshow ip bgp. The cause is usually a route-map or a kernel limit.
Diagnosis for failure point 3
show ip bgp <prefix>
show ip route <prefix>
show ip route <next-hop>
show ip bgp <prefix> rib-failure
show ip bgp <next-hop>
show configuration commands | match table-map
show configuration commands | match route-map
The first command shows the route’s state in BGP. The second shows the FIB. The third confirms the NEXT_HOP is in the FIB. The fourth shows the FRR rib-failure reason if any. The fifth shows the NEXT_HOP route’s status. The sixth and seventh show the table-map and route-map configuration that may be filtering.
The canonical production error: the operator is running OSPF and BGP on the same router. OSPF carries the NEXT_HOP, BGP has the route as valid, but OSPF has not yet converged on the NEXT_HOP. The route is *> in show ip bgp but show ip route shows the route is “incomplete” or the NEXT_HOP is recursive. The fix is to wait for OSPF to converge or to use next-hop-self on the iBGP peer.
How the result is validated
The canonical validation sequence for a missing route:
show ip bgp summary
show ip bgp neighbors <ip> received-routes | match <prefix>
show ip bgp <prefix>
show ip route <prefix>
show ip route <next-hop>
The first command shows the session state — if the session is not Established, the route will not be received. The second shows the raw inbound stream. The third shows the BGP table. The fourth shows the FIB. The fifth confirms the NEXT_HOP is reachable.
The operator who runs all five in order has the answer in 30 seconds. The operator who runs only show ip route and complains the route is missing is missing the BGP picture.
How it fails
The production failure modes the engineer must recognise:
- Session in Active, route missing. Failure point 1. The session is not exchanging UPDATEs. Fix the session first.
- Route in
received-routesbut not inshow ip bgp. Failure point 2 inbound filter. The peer sent the route; the inbound filter dropped it. Walk the inbound prefix-list, filter-list, and route-map. - Route in
show ip bgpash>(history). Failure point 2 history. The NEXT_HOP is not reachable. Check the IGP. - Route in
show ip bgpasd>(dampened). Failure point 2 damping. Route flap damping suppressed the route. Wait for decay or clear the damping. - Route in
show ip bgpasr>(rib-failure). Failure point 3 rib-failure. The route was selected by BGP but the kernel refused it. Walk the table-map and route-map. - Route in
show ip bgpas*>but not inshow ip route. Failure point 3 recursive next-hop. The NEXT_HOP is not in the IGP. - Route in
show ip bgpas*>but in a different VRF. Failure point 3 VRF mismatch. The operator is checking the wrong VRF.
Rollback
Missing-route debugging is usually diagnostic, not configuration-changing. The rollback is to revert any test configuration the operator added while debugging.
If the operator added a clear ip bgp <ip> soft in to refresh the inbound stream, the rollback is to wait — the soft refresh does not persist. If the operator added a debug log filter (debug bgp neighbor-events), the rollback is to remove the debug filter with no debug bgp neighbor-events.
If the operator changed a prefix-list or route-map during debugging, the standard rollback applies: rollback N; commit; save.
Production discipline
Cross-course references
The Linux course’s XIX-Linux-NetFoundations covers the kernel FIB. The OPNsense course’s XXX-OPNsense-DynamicRouting covers the equivalent FRR BGP on the firewall side. The BGP lessons vyos-xxiv-01-bgp-config, vyos-xxv-01-bgp-network-statement, and vyos-xxviii-01-prefix-list-concept cover the configuration primitives. The lesson vyos-xxvii-01-best-path-algorithm covers the selection algorithm that picks the winner at failure point 2. The lesson vyos-xxxii-03-bfd-with-bgp covers BFD integration that turns silent failures into fast failures.
Quiz
Knowledge check · 4 questions
Q1. An operator runs `show ip bgp 198.51.100.0/24` and the output shows `*> 198.51.100.0/24 192.0.2.2 0 64512 65001 i`. The operator runs `show ip route 198.51.100.0/24` and gets no output. Which failure point is this?
Q2. A route in `show ip bgp <prefix>` with the `h` flag (history) is in Adj-RIBs-In and is valid for selection; the `h` flag is just informational.
Q3. An operator configures a BGP peer and expects to receive the prefix 198.51.100.0/24. The operator runs `show ip bgp 198.51.100.0/24` and gets no output. The operator runs `show ip bgp neighbors 192.0.2.2 received-routes` and sees 198.51.100.0/24 in the list. Which failure point is this, and what is the most likely cause?
The peer is sending the route (it appears in received-routes, which bypasses the inbound filter). The route is not in the BGP table (show ip bgp shows nothing for the prefix). The route was filtered out by the inbound prefix-list or route-map.
Q4. An operator has a BGP route 198.51.100.0/24 with `*>` in `show ip bgp` (valid and best). The operator runs `show ip route 198.51.100.0/24` and gets no output. The operator runs `show ip route 192.0.2.2` (the NEXT_HOP) and gets no output. The IGP is OSPF. What is the most likely cause?
BGP has the route as valid and best, but the FIB does not. The NEXT_HOP (192.0.2.2) is not in the FIB. OSPF should be carrying the NEXT_HOP because the operator has iBGP to OSPF redistribution or the NEXT_HOP is directly connected. The OSPF route is missing — either not advertised or filtered.
Passing score: 75%. Answers are checked in this browser.