You run show ip bgp and the prefix is right there. You run show ip route for the same prefix and get % Network not in table. No neighbor has flapped, the session is Established, the path looks perfectly healthy, and traffic is still going somewhere else.
That gap is not a bug and almost never a mystery. BGP keeps every path it is sent, hands the routing table exactly one path per prefix, and the RIB gets the final say on whether it accepts. A prefix that sits in BGP and never reaches the RIB failed at one of those two steps, and the leading characters on each line of show ip bgp tell you which. Most engineers skim straight past them. For the wider context on how BGP chooses and installs paths, the pillar covers the attribute machinery this article assumes.
One boundary first, because these two problems get conflated constantly. If your neighbor never receives a prefix at all, that is the sending side, covered in why a router is not advertising a prefix to its neighbor. This article owns the receiving side: it arrived, you can see it, and it will not install. Everything below came off a live CML lab of three iol-xe routers on IOS XE 17.18.2, R1 in AS 65001 speaking eBGP to R2 in AS 65002, R2 speaking iBGP to R3.
Read the status codes before you read anything else
Every prefix line in show ip bgp starts with a two or three character status field, and that field is the entire diagnosis. It is explained in a legend at the top of the output that everyone reads once, in their first week, and scrolls past forever after.
Two of those matter more than the rest here. A line with * and no > means the path is valid but is not the one BGP is offering the RIB, so the failure happened inside BGP. A line with r means the opposite: BGP selected a best path, tried to install it, and the RIB pushed back. Completely different fix lists, and the difference is one character. (Do not confuse the i in the status field with the trailing origin code at the end of the same line, which is also frequently i. Same letter, different column, unrelated meanings.)
Cause 1: the next hop is not reachable
This is the one. If you take a single reflex from this article, make it "check the next hop first", because unresolved next hops account for more not-installed BGP routes than everything else combined. Here is the broken state, R3 holding 100.100.100.0/24 from its iBGP peer R2:
R3# show ip bgp 100.100.100.0/24
BGP routing table entry for 100.100.100.0/24, version 0
Paths: (1 available, no best path) <-- one path, and BGP picked none of them
Flag: 0x8100
Not advertised to any peer
Refresh Epoch 1
65001
10.0.12.1 (inaccessible) from 10.0.23.2 (2.2.2.2)
Origin IGP, metric 0, localpref 100, valid, internal
rx pathid: 0, tx pathid: 0
R3# show ip route 100.100.100.0
% Network not in tableThree things there do all the work: the next hop reads 10.0.12.1 (inaccessible), the summary says no best path despite one path being available, and the attribute line says valid, internal. That last one trips people up, because the path is flagged valid and BGP still refuses to select it. Validity is about the update being well formed, selection is a separate step, and RFC 4271's decision process disqualifies any path whose next hop cannot be resolved in the RIB before the tie-breakers ever run. BGP does not discover topology, it advertises reachability and leans recursively on the local routing table to reach the next hop. R3 has no route to 10.0.12.1, so everything stops there.
Why is the next hop unreachable? 10.0.12.1 is R1's address on the R1 to R2 link, a subnet R3 has no route to. R2 passed the prefix from eBGP into iBGP and left the next hop untouched, which is specified behaviour rather than a bug (the assumption being that everyone inside the AS can reach the AS boundary). If your edge links are not in the IGP, that assumption is false and every downstream speaker inherits a path it cannot use.
Confirm it in one command: take the next hop out of the BGP entry and run show ip route 10.0.12.1. If that returns % Network not in table, you are done diagnosing, with no need to look at attributes or filters at all.
The fix, and what an installed path looks like
Two honest options: advertise the edge subnet into your IGP so every internal router can resolve it, or have the border router rewrite the next hop to itself. The second is the standard answer, and the entire reason next-hop-self exists:
router bgp 65002
neighbor 10.0.23.1 next-hop-self
!
clear ip bgp 10.0.23.1 soft outApplied on R2, that rewrites the next hop to R2's own iBGP-facing address, which R3 reaches over a directly connected /30, and the soft clear pushes the updated attributes without tearing the session down. R3 immediately afterwards:
R3# show ip bgp 100.100.100.0/24
BGP routing table entry for 100.100.100.0/24, version 2
Paths: (1 available, best #1, table default)
65001
10.0.23.2 from 10.0.23.2 (2.2.2.2)
Origin IGP, metric 0, localpref 100, valid, internal, best
R3# show ip route 100.100.100.0
Routing entry for 100.100.100.0/24
Known via "bgp 65002", distance 200, metric 0
Tag 65001, type internal
* 10.0.23.2, from 10.0.23.2, 00:00:17 agoSame prefix, same peer, same AS path. The only change is a next hop the local RIB can resolve, and the path goes from no best path to best #1 and lands in the routing table. Note distance 200 and type internal, because that becomes cause five. If the fields in that entry are not second nature yet, ten minutes on what each part of a Cisco routing table entry actually means pays for itself, since half of BGP troubleshooting is really RIB reading.
Cause 2: valid, but not best
If the prefix has several paths and one carries >, the others are working as designed. BGP is not a load balancer by default: it picks a single winner, and only that winner is offered to the RIB and re-advertised. Every other path sits there as a warm standby.
This becomes a real complaint when the winner is not the one you wanted, which produces the same phone call even though the prefix is in the RIB, just via a next hop nobody expected. Work down the order BGP compares paths in until you find the step that decided it, remembering that weight and local preference sit near the top, so a stray inbound route-map beats any amount of AS path engineering further down. If you want two paths installed, that is maximum-paths: opt-in, fussy about attribute equality, and not a fallback for a path that lost.
Cause 3: it never reached this router in the first place
Look again at one line in the broken capture: Not advertised to any peer. A path that is not best is not propagated, so R3 not only failed to install the prefix, it declined to pass it on, and a single unresolved next hop silently blackholes every device behind it.
The related trap is iBGP split horizon. A route learned from an iBGP peer is never advertised to another iBGP peer, full stop, because there is no AS path loop prevention inside an AS (which is why iBGP needs a full mesh, or route reflectors to fake one). From the far end that looks identical to a filtering problem. Tell them apart at the middle router: prefix present there and absent downstream means split horizon or a non-best path, not a filter. Check the session is genuinely up while you are there, because a peer that keeps resetting shows prefixes appearing and vanishing, which reads as an install problem when it is really a neighbor that is not staying in Established.
Cause 4: synchronisation, and why it is probably not your problem
The old synchronisation rule said a router must not use or advertise an iBGP-learned route until the same prefix appeared in its IGP, so that non-BGP routers in the middle of the AS would not black-hole transit traffic. It has been off by default since IOS 12.2(8)T and stays off on modern IOS XE, so on any current box this is not your problem. It earns a mention only because it appears in CCNP question banks and still lurks in configs copied from a 2003 template.
Cause 5: something with a better administrative distance already owns the prefix
This is what the r code exists for, and it is the most misread symptom in the list. RIB-failure does not mean BGP failed. It means BGP selected a best path, offered it to the routing table, and the routing table declined because it already holds that prefix from a source it trusts more.
The numbers make it obvious. eBGP installs at AD 20, beating OSPF at 110 and EIGRP at 90. iBGP installs at AD 200, losing to essentially every IGP and to any static route. Look back at the working capture: distance 200. Had that prefix also been present via OSPF, OSPF would have won and the BGP path would be flagged r instead. The asymmetry is deliberate, and the full picture of which routing source wins when two protocols offer the same prefix is worth keeping to hand.
Reach for show ip bgp rib-failure, which lists every prefix BGP could not install and why. Note the sting in the tail: a RIB-failed route is still advertised to your peers, so you are telling the world you can reach a prefix while forwarding it by a different protocol's idea of the topology.
Cause 6: inbound filtering, which looks like the same problem
If the prefix is not in show ip bgp at all, the update was either never sent or discarded on arrival. Prove which by comparing what the peer sent against what you kept. With neighbor x.x.x.x soft-reconfiguration inbound configured, show ip bgp neighbors x.x.x.x received-routes gives the pre-policy view and show ip bgp neighbors x.x.x.x routes the post-policy view. A prefix in the first and not the second is your own prefix-list, distribute-list, or route-map eating it.
The subtler version does belong here. An inbound route-map can leave a prefix visible but unusable, most cruelly with set ip next-hop pointing at an address the router cannot resolve, reproducing the (inaccessible) symptom from cause one on a router where the peering is fine and the neighbor is blameless. If the next hop is not an address you expected, read your own inbound policy before you call the other side.
What this was captured on
Three iol-xe nodes in Cisco Modeling Labs on IOS XE 17.18.2. R1 in AS 65001 originates 100.100.100.0/24 from a loopback and peers eBGP with R2 over 10.0.12.0/30. R2 in AS 65002 peers iBGP with R3 over 10.0.23.0/30 and starts without next-hop-self, which is the entire break, and R3 has no route to the edge link. Output was collected on-box by an EEM applet writing show results to syslog, read back through the CML console log API, so everything above is verbatim.
Gotchas
- "valid" does not mean installable. The capture shows
valid, internalalongsideno best pathin one output. Validity and selection are different gates, with next-hop resolution between them. (inaccessible)ends the investigation. Read the next-hop line before the attribute line, every time.- eBGP next hops pass into iBGP unchanged. If your edge links are not in the IGP, the symptom lands on routers that have no idea the eBGP session exists.
- A non-best path is not advertised onward. One router's next-hop failure shows up downstream as a total absence of the prefix.
- Use a soft clear.
clear ip bgp <peer> soft outre-sends updates without dropping the session. A hardclear ip bgp *on a production edge is a resume-generating event.
Key takeaways
- The BGP table and the RIB are separate structures. A prefix can live in one and not the other, permanently, with nothing logging an error.
- Read the status characters first. No
>means BGP did not select the path, anrmeans the RIB refused it. Different problems, different fixes. - Check next-hop reachability before anything else.
show ip route <next-hop>answers the most common cause in one command, andnext-hop-selfis the standard fix. - An installed iBGP route carries AD 200, so any IGP holding the same prefix wins and pushes BGP into RIB-failure while you keep advertising the prefix to peers.
- If the prefix is not in
show ip bgpat all, that is the other problem, and the diagnosis moves to the sending side and your inbound policy.
Next hop, then best path, then RIB. Three checks in that order resolve almost every instance of this, and all three are quicker than reading configuration. The rest of the BGP troubleshooting and design series covers the attributes and neighbor states either side of this one.