Latest Cisco, PMP, AWS, CompTIA, Microsoft Materials on SALE Get Now Get Now

Mutual Route Redistribution Loop Prevention: The Loop Lives in the Routing Table, Not in Either Protocol

Mutual redistribution at a single router is safe. Mutual redistribution at two routers is where networks break, and the mechanism is not subtle once you see it: a route leaves its home protocol at one boundary, travels through the second protocol, arrives back at the other boundary, and is redistributed home again — now carrying a different administrative distance. If that distance is better than the one the route natively has, a router prefers the copy that came the long way round, points at a next hop in the wrong direction, and the traffic loops.

The reason this catches experienced engineers is that the loop does not involve either protocol malfunctioning. EIGRP's DUAL is loop-free, OSPF's SPF is loop-free, and both are working correctly on their own routes. The loop lives in the routing table, between the protocols, in the administrative-distance comparison that decides which of two correct answers to install. Neither protocol can see the other's copy of the route as anything other than a legitimate advertisement from a neighbour, because from the protocol's perspective that is exactly what it is.

This article builds the loop deliberately and then removes it. Section one lays out the topology and shows the failure. Section two walks the administrative distances step by step so the mechanism is unambiguous. Section three implements route tagging, which is the answer that scales. Section four covers the alternatives — prefix filtering and distance manipulation — and when each is defensible. Section five is verification: how to prove the loop is gone rather than currently dormant.

Blog ClaimThe loop in mutual redistribution is not a protocol failure but an administrative-distance decision, which is why no amount of tuning inside either protocol fixes it and why the only durable answer is to mark routes as they leave and refuse them as they return.
 
A prefix native to EIGRP leaves through R1, crosses OSPF, returns through R2, and arrives back with an administrative distance that beats the original — the loop is created by the distance comparison, not by either protocol.

What Does the Lab Topology Look Like and Why Does It Loop?

What is the minimum configuration that fails?

Two routers, R1 and R2, each connected to both an EIGRP domain and an OSPF domain, each configured to redistribute in both directions with no filtering. R3 originates 10.5.0.0/16 in EIGRP. R5 lives in OSPF. Every statement is individually correct and the reachability test passes on the first try, which is precisely why the configuration ships. The failure appears later — sometimes immediately, sometimes only when a link fails and the metrics shift — and it appears as traffic taking an absurd path or not arriving at all. What makes it hard to attribute is that the change which exposes it is usually unrelated to redistribution — a link failure, a metric adjustment, a new prefix — so the investigation starts somewhere other than the boundary routers.

A Deeper Dive into the Failing Configuration

The configuration that produces the loop

! ===== R1: mutual redistribution, no tags, no filters =====
router ospf 1
 redistribute eigrp 100 metric 20 subnets
 network 10.0.1.0 0.0.0.255 area 0
!
router eigrp CORP
 address-family ipv4 unicast autonomous-system 100
  topology base
   redistribute ospf 1 metric 1000000 100 255 1 1500
  exit-af-topology
  network 10.1.0.0 0.0.255.255
 exit-address-family
!
! ===== R2: identical. That is the whole problem. =====
router ospf 1
 redistribute eigrp 100 metric 20 subnets
 network 10.0.2.0 0.0.0.255 area 0
!
router eigrp CORP
 address-family ipv4 unicast autonomous-system 100
  topology base
   redistribute ospf 1 metric 1000000 100 255 1 1500
  exit-af-topology
  network 10.2.0.0 0.0.255.255
 exit-address-family

What the failure looks like

! On R1, a prefix that originated in EIGRP two hops away
R1# show ip route 10.5.0.0
Routing entry for 10.5.0.0/16
  Known via "ospf 1", distance 110, metric 20, type extern 2
  Last update from 10.0.1.2 on GigabitEthernet0/1
  * 10.0.1.2, from 10.0.2.1, 00:02:14 ago, via GigabitEthernet0/1
! ^ R1 is pointing INTO OSPF for a prefix that lives in EIGRP
!   behind it. The EIGRP path is still there but lost at AD 170.
!
! The traceroute makes it obvious
R1# traceroute 10.5.0.1
  1 10.0.1.2 [OSPF core]  1 msec
  2 10.0.2.1 [R2]         1 msec
  3 10.1.0.1 [R1]         2 msec
  4 10.0.1.2              2 msec
  5 10.0.2.1              3 msec
! ^ R1 and R2 handing the packet back and forth until TTL expires.

Why the reachability test passed

Immediately after configuration, R1 typically still has the native EIGRP route, because the redistributed copy has not completed its round trip yet. A ping from R1 succeeds, the change is marked complete, and the loop forms seconds or minutes later when the OSPF external LSA propagates back and the distance comparison runs again. A test performed within the first few seconds of a mutual redistribution proves nothing at all. Waiting for the second protocol to converge fully — which on OSPF means the external LSA reaching every router and the SPF running everywhere — before testing is the difference between a verification and a coincidence.

Pitfall: a second redistribution point added later, by someone else Symptom: a network that has run correctly for years develops routing loops or long detours shortly after a new site, a new core router, or a redundant boundary is commissioned. Nothing about the original configuration changed. Cause: the original design had one redistribution point and needed no loop prevention, so none was configured. Adding a second boundary turned a safe configuration into an unsafe one without touching it. Confirm: show running-config | include redistribute across all boundary routers; more than one router redistributing in both directions between the same protocol pair, with no route-map, is the finding. Fix: apply the tag scheme to every boundary including the original one. The original router's configuration is now wrong even though it has not changed, which is why "we did not touch it" is not evidence that it is still correct.
One redistribution point is safeWith a single router doing mutual redistribution, a route leaving one protocol has no second boundary to come back through. The router will not redistribute a route back into the protocol it learned it from, because after redistribution the route is no longer sourced from that protocol in the RIB. Every problem in this article requires two or more redistribution points, which is also why the fix is only needed there.
Build the loop once, in a labConfigure the failing version, watch the traceroute alternate between two routers, then apply the fix and watch it stop. Ten minutes of doing that makes the administrative-distance mechanism permanent knowledge in a way that reading about it does not, and it is the single most useful lab exercise in the redistribution topic.
Sub claimThe configuration that loops is the one where every individual statement is correct — which is why the failure is a design property of having two redistribution points rather than a mistake in any command.

How Does Administrative Distance Create the Loop?

What is the exact sequence?

A prefix originates in protocol A and is known at both boundary routers with A's native distance. R1 redistributes it into protocol B, where it becomes an external route with B's external distance. That copy propagates through B and reaches R2, which redistributes it back into A as an A-external route with A's external distance. R1 now holds two entries for the prefix: the original from A at A's internal distance, and the copy from B at B's distance. If B's distance is lower, R1 installs the copy — whose next hop points into B, away from the prefix's actual location — and the packet is handed back and forth between R1 and R2.

A Deeper Dive into the Distance Mechanics

The distances that decide it

Route source Administrative distance Beats Loses to
Connected 0 Everything Nothing
Static 1 All dynamic protocols Connected
eBGP 20 All IGPs Static, connected
EIGRP internal 90 OSPF, IS-IS, RIP, EIGRP external eBGP, static, connected
OSPF (internal and external alike) 110 IS-IS, RIP, EIGRP external EIGRP internal, eBGP
IS-IS 115 RIP, EIGRP external OSPF, EIGRP internal
RIP 120 EIGRP external OSPF, IS-IS, EIGRP internal
EIGRP external 170 iBGP only Everything else
iBGP / local BGP 200 Nothing Everything

The row that matters is EIGRP external at 170. OSPF does not distinguish internal from external in its distance — both are 110 — so an OSPF copy of an EIGRP-originated route always beats the EIGRP external copy coming back, and frequently beats nothing else because the original EIGRP internal route at 90 is still better. The loop forms specifically where the original is not present at 90 on the router making the decision.

The case where it bites hardest

Consider a prefix that was itself redistributed into EIGRP from somewhere else — a static route, a connected interface on a third router, another protocol. It exists in EIGRP as an external route at distance 170. Now the OSPF copy returning at 110 beats it everywhere, including on the router that originally injected it, and every router in the EIGRP domain prefers the path through OSPF. That is not merely suboptimal; on the injecting router it is a loop.

! R3 redistributes a static into EIGRP - it is EIGRP EXTERNAL, AD 170
R3(config)# ip route 10.5.0.0 255.255.0.0 10.9.0.1
R3(config-router-af-topology)# redistribute static metric 1000000 100 255 1 1500
!
! On R3 the static still wins locally at AD 1, so R3 is fine.
R3# show ip route 10.5.0.0 | include Known via
  Known via "static", distance 1
!
! But R1, which has no static, compares 170 against 110
R1# show ip route 10.5.0.0 | include Known via
  Known via "ospf 1", distance 110
! ^ R1 prefers the OSPF copy of a prefix that reaches it through EIGRP.
!   Every EIGRP router between R1 and R3 now points the wrong way.

Why split horizon does not help either

Split horizon prevents a protocol from advertising a route back out the interface it learned it on, which is real loop prevention within a protocol. It does nothing here because the route does not return by the same protocol — it leaves as EIGRP, comes back as OSPF, and the two protocols have no shared state that would let either recognise the other's copy as its own. The same reasoning applies to EIGRP's feasibility condition and OSPF's SPF: both guarantee loop freedom over the topology their own protocol computed, and neither has any visibility into a path that left and returned through a different one.

Why the metric does not save you

Administrative distance is compared before metric and across protocols; metric is compared only within a protocol. A redistributed route with an appalling metric still wins against a native route with an excellent one if its distance is lower. That is why setting a very high seed metric feels like it should help and does not — the comparison never reaches the metric.

! An enormous seed metric changes nothing about the outcome
router ospf 1
 redistribute eigrp 100 metric 16777214 subnets
!
R1# show ip route 10.5.0.0
  Known via "ospf 1", distance 110, metric 16777214, type extern 2
! ^ Still installed. AD 110 beat AD 170 before the metric mattered.

Suboptimal routing, which is the same problem without the loop

Not every distance inversion produces a loop. Where the returning copy wins on a router that is not in the return path, the result is a working but longer path — traffic that should have left through the nearby boundary crosses the network to the far one. This is more common than an outright loop and considerably harder to notice, because everything reaches its destination and only latency and link utilisation reveal it.

The cause is identical and so is the fix. A router preferring an external copy of a prefix it could reach natively is making the same wrong comparison; whether that produces a loop or merely a detour depends on where the router sits relative to the two boundaries. Treating suboptimal routing across a redistribution boundary as a symptom of the same problem, rather than as a separate tuning exercise, saves considerable time.

! R4 sits deep in EIGRP, two hops from R3 which originates the prefix
R4# show ip route 10.5.0.0
  Known via "eigrp 100", distance 170, metric 3072000, type external
  * 10.1.0.2, from 10.1.0.2, via GigabitEthernet0/1
! ^ AD 170 means this is the copy that came back through OSPF,
!   not the native EIGRP route. No loop - R4 is not a boundary -
!   but the path crosses the OSPF domain and returns.
!
R4# traceroute 10.5.0.1
  1 10.1.0.2 [R2]      1 msec
  2 10.0.2.2 [core]    2 msec
  3 10.0.1.1 [R1]      3 msec
  4 10.1.0.1 [R3]      4 msec
  5 10.5.0.1           4 msec
! ^ Four hops through OSPF to reach something two hops away in EIGRP.
!   It works. It is still the redistribution problem.

Protocol pairs and their risk

Pair Direction at risk Why Severity
EIGRP and OSPF OSPF copy returning into EIGRP 110 beats EIGRP external 170 High — the classic case
EIGRP and RIP RIP copy returning into EIGRP 120 beats EIGRP external 170 High
OSPF and RIP OSPF copy returning into RIP 110 beats RIP 120 High
OSPF and IS-IS OSPF copy returning into IS-IS 110 beats IS-IS 115 Moderate
Two OSPF processes Either direction Both are 110 — metric decides, unpredictably High
Two EIGRP autonomous systems Either direction Both externals are 170 High
IGP and BGP Usually safe iBGP 200 loses to every IGP Low
Pitfall: assuming EIGRP's low distance protects you Symptom: a network running EIGRP and OSPF with mutual redistribution works correctly for internally originated prefixes and loops for anything that was redistributed into EIGRP from a third source. Cause: EIGRP internal routes at distance 90 do beat the returning OSPF copy at 110, so natively originated prefixes are safe. EIGRP external routes are at 170 and lose, so every prefix that entered EIGRP by redistribution is exposed. Confirm: show ip route <prefix> on a boundary router shows ospf as the source for a prefix that should be reached through EIGRP; show ip eigrp topology <prefix> shows it present but not installed. Fix: tag on export and deny on import. Distance 90 protecting some prefixes is not protection; it is a partial failure that hides the problem until the exposed prefixes matter.
Sub claimEIGRP internal at 90 survives the round trip and EIGRP external at 170 does not, which means a network can appear to work perfectly while every redistributed prefix in it is one topology change away from looping.

How Do I Prevent It with Route Tags?

What is the tagging pattern?

On every redistribution point, in every direction: set a tag identifying the source protocol as the route leaves, and deny any route carrying that same tag as routes come back in. A route tagged 90 on its way from EIGRP into OSPF is, by definition, one that this network already had in EIGRP — so refusing to redistribute anything tagged 90 back into EIGRP closes the loop without needing to know which prefixes exist. The scheme scales because it is prefix-independent: adding a new subnet anywhere requires no change to the tagging configuration.

A Deeper Dive into Tag-Based Prevention

The complete configuration, both directions, both routers

! ===== Tag convention =====
!   90  = this route came from EIGRP
!   110 = this route came from OSPF
! Any value works; consistency across all boundary routers is
! what matters.
!
! ===== EIGRP -> OSPF =====
route-map EIGRP-TO-OSPF deny 10
 match tag 110
 ! Refuse anything OSPF gave us in the first place
route-map EIGRP-TO-OSPF permit 20
 set tag 90
!
! ===== OSPF -> EIGRP =====
route-map OSPF-TO-EIGRP deny 10
 match tag 90
 ! Refuse anything EIGRP gave us in the first place
route-map OSPF-TO-EIGRP permit 20
 set tag 110
! ===== Applied identically on R1 AND R2 =====
router ospf 1
 redistribute eigrp 100 metric 20 metric-type 1 subnets route-map EIGRP-TO-OSPF
 network 10.0.1.0 0.0.0.255 area 0
!
router eigrp CORP
 address-family ipv4 unicast autonomous-system 100
  topology base
   redistribute ospf 1 metric 1000000 100 255 1 1500 route-map OSPF-TO-EIGRP
  exit-af-topology
  network 10.1.0.0 0.0.255.255
 exit-address-family
! ^ Both routers, identical maps. A single untagged boundary
!   reintroduces the loop for every prefix crossing it.
Apply both routers in one change windowTagging one boundary and not the other leaves the network in a state where routes crossing the untagged boundary still make the round trip, which is the original problem with half the configuration in place. Prepare both routers' configuration, apply them together, and verify afterwards — a partial rollout of a loop-prevention scheme provides no partial protection.

Why it works without knowing the prefixes

The tag is a statement about provenance rather than about identity. A route arriving in OSPF with tag 90 says "an EIGRP-to-OSPF boundary in this network put me here", and the only correct response at an OSPF-to-EIGRP boundary is to leave it alone — EIGRP already has it by a shorter path. That reasoning holds for every prefix, including ones created after the configuration was written, which is exactly what prefix-list filtering cannot offer.

! Verify the tag survives the transition
R5# show ip route 10.5.0.0
  Known via "ospf 1", distance 110, metric 30, type extern 1
  Tag 90
!
! And that the reverse direction refuses it
R2# show ip eigrp topology 10.5.0.0/16
! Present via EIGRP natively, NOT as a redistributed external.
!
! On R1, the native path wins again
R1# show ip route 10.5.0.0 | include Known via
  Known via "eigrp 100", distance 90
The deny clause must come firstA route-map is evaluated in sequence order and stops at the first match, so the clause that denies returning routes must have a lower sequence number than the permissive clause that tags everything else. Reversing them makes the permit clause match every route including the ones you meant to reject, and the deny clause becomes unreachable — a configuration that looks complete, contains both halves of the scheme, and prevents nothing.

Tag values and where they are carried

Protocol Tag width Carried in Survives redistribution
OSPF 32 bits External Route Tag in Type 5 and Type 7 LSAs Yes
EIGRP 32 bits Administrator Tag in the external route TLV Yes
IS-IS 32 bits Administrative tag sub-TLV Yes
RIPv2 16 bits Route Tag field Yes, truncated to 16 bits
BGP No native tag Use a community and translate
Static 32 bits Set on the ip route statement Yes, once redistributed

Designing the tag scheme

Two conventions are common and both work. The simplest uses the administrative distance of the source protocol as the tag value — 90 for EIGRP, 110 for OSPF, 120 for RIP — which is self-documenting and needs no lookup table. The more structured approach encodes the source protocol and the boundary router, so a route arriving with tag 90001 says "EIGRP, via boundary 1", which is useful in a network with several boundaries because it identifies which one leaked a route that should not have crossed.

Whichever you choose, two properties matter more than the values. Every boundary router uses the same values, because a mismatched tag at one boundary means the others do not recognise its routes. And the scheme is written down somewhere that survives the engineers, because a match tag 90 with no explanation is indistinguishable from a mistake and will eventually be removed by somebody tidying up.

! Convention A: tag = the source protocol's administrative distance
!   90  EIGRP    110 OSPF    115 IS-IS    120 RIP    200 BGP
! Self-documenting; no table needed.
!
! Convention B: source protocol and boundary identity
!   9001 = EIGRP via boundary 1     9002 = EIGRP via boundary 2
!   1101 = OSPF  via boundary 1     1102 = OSPF  via boundary 2
!
! Convention B lets you deny by source while still identifying
! which boundary a stray route came through
route-map OSPF-TO-EIGRP deny 10
 match tag 9001 9002
route-map OSPF-TO-EIGRP permit 20
 set tag 1101
!
! And makes an audit possible
R3# show ip route | include Tag 9002
! ^ Every route that crossed via boundary 2, listed.

The BGP exception

BGP carries no route tag, so a tag set on an IGP route is lost the moment it enters BGP and cannot be recovered on the way out. The equivalent is a community: set a community when redistributing into BGP, match that community when redistributing out. The translation has to be written explicitly in both directions, and forgetting one half produces exactly the loop the tag scheme was meant to prevent.

! IGP tag -> BGP community on the way in
route-map OSPF-TO-BGP deny 10
 match community FROM-BGP
route-map OSPF-TO-BGP permit 20
 set community 65000:110 additive
!
! BGP community -> IGP tag on the way out
route-map BGP-TO-OSPF deny 10
 match community FROM-OSPF
route-map BGP-TO-OSPF permit 20
 set tag 200
!
ip community-list standard FROM-OSPF permit 65000:110
ip community-list standard FROM-BGP  permit 65000:200
Tag from the first redistribution point, not the secondAdding tags when a second boundary is introduced means editing a live redistribution during the change that also introduces the loop risk. Tagging from the start, when there is one boundary and no loop is possible, means the second boundary is a purely additive change with a configuration that is already correct.
Sub claimA tag records where a route has already been, which makes tag-based prevention independent of the prefix list — and prefix independence is the only property that survives a network that keeps growing.

What Are the Alternatives and When Are They Right?

What else can close the loop?

Two things, both inferior to tagging in the general case and both defensible in specific ones. Prefix filtering enumerates which prefixes may cross in each direction, which is exact and auditable and requires editing every time the address plan changes. Administrative distance manipulation raises the distance of the returning copy — or lowers the native route's — so the native path always wins the comparison, which is a single command and is fragile because it depends on distances staying as configured everywhere. A third option, which is not a workaround at all, is to remove the second redistribution point.

A Deeper Dive into the Alternatives

Prefix filtering

Listing what may cross is unambiguous and easy to review, and it is the right answer when the set is small, stable, and externally specified — a handful of prefixes that a contract or a security policy defines. It is the wrong answer in a growing network, because every new subnet requires a change on every boundary router and the failure mode of forgetting is either a missing route or a returning loop.

! Only these prefixes cross from EIGRP into OSPF
ip prefix-list EIGRP-ORIGINATED seq 5 permit 10.1.0.0/16 le 24
ip prefix-list EIGRP-ORIGINATED seq 10 permit 10.5.0.0/16 le 24
!
route-map EIGRP-TO-OSPF permit 10
 match ip address prefix-list EIGRP-ORIGINATED
 set tag 90
! implicit deny keeps everything else out
!
! And only these cross the other way
ip prefix-list OSPF-ORIGINATED seq 5 permit 10.2.0.0/16 le 24
!
route-map OSPF-TO-EIGRP permit 10
 match ip address prefix-list OSPF-ORIGINATED
 set tag 110
! ^ Correct today. Wrong the first time somebody adds a subnet.

Administrative distance manipulation

Raising the distance of the returning route above the native one makes the native path win. On OSPF the tool is distance ospf external; on EIGRP it is distance eigrp with separate internal and external values. It is one line and it works, and it is fragile: the change must be applied on every router that could receive the returning copy, not just the boundaries, and it silently changes the outcome of every other distance comparison involving that protocol.

! Make OSPF externals lose to EIGRP externals (170)
router ospf 1
 distance ospf external 180
! ^ Now the returning OSPF copy at 180 loses to EIGRP's 170.
!   It also loses to RIP at 120 and IS-IS at 115, which may or
!   may not be what anybody wanted.
!
! Or per-source, which is narrower but harder to maintain
access-list 20 permit 10.5.0.0 0.0.255.255
router ospf 1
 distance 180 10.0.2.1 0.0.0.0 20
!         AD   source-router  wildcard  acl
!
! EIGRP: internal and external distances are set together
router eigrp CORP
 address-family ipv4 unicast autonomous-system 100
  topology base
   distance eigrp 90 175
  exit-af-topology
 exit-address-family
Distance manipulation is a fine incident responseWhen a loop is live and traffic is down, a single distance command that makes the native route win restores service in seconds, and that is worth a great deal at three in the morning. The mistake is leaving it there afterwards. Treat it as a tourniquet: apply it, restore service, then implement the tag scheme during the follow-up change and remove the distance command in the same window.

Removing the second boundary

The option people skip. A second redistribution point exists for redundancy, and redundancy can often be provided differently: a summary route or a default from one domain to the other covers the failure of the single boundary without a second full redistribution. Where the second boundary exists because two sites each grew their own, consolidating is a design cleanup rather than a workaround, and it removes the problem rather than managing it.

! One boundary does full mutual redistribution
! R1 only:
router ospf 1
 redistribute eigrp 100 metric 20 metric-type 1 subnets
!
! R2 provides a backup path with a summary, not redistribution
router eigrp CORP
 address-family ipv4 unicast autonomous-system 100
  af-interface GigabitEthernet0/1
   summary-address 0.0.0.0 0.0.0.0
  exit-af-interface
 exit-address-family
! ^ EIGRP gets a default via R2 if R1 fails. No second
!   redistribution point, therefore no loop to prevent.

The three compared

Approach Scales with new prefixes Survives a topology change Configuration burden When it is right
Route tagging Yes Yes Two route-maps per boundary Almost always
Prefix filtering No — edit every boundary Yes Grows with the address plan Small, fixed, externally specified sets
Distance manipulation Yes No — depends on distances everywhere One line, wide blast radius A temporary fix during an incident
Single boundary Yes Yes None — removes the problem Where redundancy can come from a summary
Tagging plus filtering Yes Yes Highest Where a policy also constrains which prefixes cross
Pitfall: distance manipulation as a permanent fix Symptom: a distance command applied years ago to resolve a redistribution loop causes an unrelated routing anomaly after a new protocol is introduced, and nobody can explain why routes from that protocol are being ignored. Cause: administrative distance is global to the protocol on that router, so changing it to win one comparison changes the outcome of every other comparison involving that protocol — including ones that did not exist when the change was made. Confirm: show running-config | include distance on the affected routers, compared against the platform defaults. Fix: replace it with tag-based filtering, which affects only the redistribution it is attached to, and remove the distance command. Keep distance manipulation for incident response, where a single line that works immediately has real value.
Sub claimPrefix filtering is exact and does not scale, distance manipulation scales and is not contained, and tagging is the only approach that is both — which is why the alternatives are situational and tagging is the default.

How Do I Verify the Loop Is Actually Gone?

What proves it rather than suggesting it?

Four checks. On each boundary router, confirm the native path won — show ip route for a sample prefix should name the protocol it actually originated in, not the other one. Confirm the tag is present on routes that crossed, because a missing tag means the route-map did not run. Confirm the reverse redistribution is refusing them, by checking that the destination protocol's database does not contain routes it originated. And traceroute across the boundary in both directions, because the routing table can look correct on each router individually while the forwarding path still alternates.

A Deeper Dive into Verification

Why the routing table alone is not enough

Each router's table can look entirely reasonable while the forwarding path still loops, because a loop is a property of the sequence of routers rather than of any one of them. R1 pointing at R2 is correct in isolation; R2 pointing back at R1 is also correct in isolation; the two together are the loop. That is why the verification sequence ends with a traceroute rather than with a routing table, and why checking only the router you happen to be logged into is the most common incomplete verification.

Check one: the native path won

! A prefix that originated in EIGRP, checked on both boundaries
R1# show ip route 10.5.0.0 | include Known via
  Known via "eigrp 100", distance 90
R2# show ip route 10.5.0.0 | include Known via
  Known via "eigrp 100", distance 90
! ^ Both boundaries prefer EIGRP for an EIGRP-native prefix.
!
! And a prefix that originated in OSPF
R1# show ip route 10.2.0.0 | include Known via
  Known via "ospf 1", distance 110

Check two: tags are present and correct

! In OSPF, EIGRP-sourced prefixes carry tag 90
R5# show ip route 10.5.0.0 | include Tag
  Tag 90
!
! In EIGRP, OSPF-sourced prefixes carry tag 110
R3# show ip route 10.2.0.0 | include Tag
  Tag 110
!
! Anything with no tag crossed a boundary with no route-map
R5# show ip route ospf | include ^O E
! Cross-reference against the tagged set; an untagged external
! is a boundary somebody configured without the map.

Check three: the reverse direction is refusing

! EIGRP should NOT contain externals for its own prefixes
R2# show ip eigrp topology 10.5.0.0/16 | include External
! (no output - it is a native internal route, not an external)
!
! OSPF should NOT have external LSAs for OSPF-native prefixes
R1# show ip ospf database external | include 10.2.0.0
! (no output)
!
! Count the externals in each protocol and compare to expectation
R5# show ip route ospf | count ^O E
Number of lines which match regexp = 47
R3# show ip route eigrp | count ^D EX
Number of lines which match regexp = 31
! ^ 47 EIGRP-originated prefixes in OSPF, 31 OSPF-originated in
!   EIGRP. If either number is close to the sum of both, routes
!   are making the round trip and the tags are not working.

Check four: traceroute, both directions

! From the OSPF side into EIGRP
R5# traceroute 10.5.0.1
  1 10.0.1.1 [R1]     1 msec
  2 10.1.0.1 [R3]     2 msec
  3 10.5.0.1          2 msec
! ^ Straight through. No router appears twice.
!
! And back
R3# traceroute 10.2.0.1
  1 10.1.0.2 [R1]     1 msec
  2 10.0.1.2 [core]   2 msec
  3 10.2.0.1          2 msec
!
! The failure signature, for comparison
!   3 10.1.0.1 [R1]
!   4 10.0.1.2
!   5 10.0.2.1 [R2]
!   6 10.1.0.1 [R1]     <- R1 appears twice = loop

Keeping it correct after the change

Tag schemes decay. A new boundary router is built from a template that predates the scheme; an engineer adds a redistribution during an incident and does not attach the map; a device is replaced and its configuration restored from a backup taken before the tags were added. Each of these reintroduces the problem for whatever crosses that boundary, and none of them produces an error at the time.

Two cheap audits catch it. A configuration check that every redistribute statement has a route-map attached finds the missing map directly. And a routing-table check for external routes carrying no tag finds routes that crossed a boundary without one, which is the same finding from the other end and works even when the offending router is not in your configuration management.

! Audit 1: every redistribute statement has a route-map
R1# show running-config | include redistribute
   redistribute eigrp 100 metric 20 metric-type 1 subnets route-map EIGRP-TO-OSPF
   redistribute ospf 1 metric 1000000 100 255 1 1500 route-map OSPF-TO-EIGRP
! ^ Any line without 'route-map' is a finding.
!
! Audit 2: external routes with no tag
R5# show ip route ospf | include ^O E
! ...then check a sample for the Tag line
R5# show ip route 10.7.0.0 | include Tag
! (no output) = this prefix crossed a boundary with no route-map
!
! Audit 3: does any boundary disagree about the tag values?
R2# show running-config | include set tag|match tag
 match tag 110
 set tag 90
 match tag 90
 set tag 110
! ^ Compare against R1. They must be identical.

Testing under failure, which is where loops appear

A tag scheme that works in steady state can still be incomplete if one boundary was configured and another was not, because the misconfigured boundary only matters when it becomes the active path. Shutting each boundary in turn, and repeating the four checks with the other carrying everything, is the test that finds the boundary somebody missed.

! Fail one boundary and re-verify everything
R1(config)# interface GigabitEthernet0/1
R1(config-if)# shutdown
!
R5# traceroute 10.5.0.1
R3# show ip route 10.2.0.0 | include Known via|Tag
R2# show ip route 10.5.0.0 | include Known via
!
R1(config-if)# no shutdown
! Then repeat with R2 shut instead.
Check Command Expected Failure signature
Native path wins show ip route <prefix> Source protocol matches origin The other protocol is the source
Tag present show ip route <prefix> | include Tag The expected tag value No Tag line
Reverse refused Protocol database for own prefixes No external entry External entry for a native prefix
Counts sane count ^O E / count ^D EX Each roughly the other domain's size Either close to the total of both
Forwarding path traceroute both directions No router appears twice Two routers alternating
Under failure All of the above with one boundary shut Unchanged A loop appears only in this state
Exam contextMutual redistribution loop prevention is a standing item in the CCIE Enterprise Infrastructure blueprint and is examined as a build-and-repair task: a topology is supplied with two redistribution points and a requirement for optimal routing, and the expected answer is tag-based filtering rather than distance manipulation. The reliably tested points are that EIGRP external at 170 loses to OSPF at 110, that the tag must be set in one direction and matched in the other at every boundary, and that a solution working on one boundary only is incomplete. ENARSI 300-410 covers the same scenario with more emphasis on the verification commands.
Sub claimA traceroute in both directions with each boundary failed in turn is the only test that exercises the state in which an incomplete tag scheme actually loops.

Conclusion

The mutual-redistribution loop is a routing-table problem wearing routing-protocol clothes. Both protocols are behaving correctly: EIGRP's DUAL is loop-free, OSPF's SPF is loop-free, and each is faithfully advertising a route it legitimately learned. What fails is the comparison between them, which happens in the RIB, uses administrative distance, and has no visibility into whether the two entries describe the same physical path traversed in opposite directions. No amount of metric tuning reaches that comparison, because distance is evaluated first.

Route tagging works because it adds the one piece of information the comparison lacks: where the route has already been. A tag set as a prefix leaves EIGRP travels with it through OSPF and is still there when it reaches the boundary that would send it back. Refusing tagged routes at that point is a statement about provenance rather than about addresses, which is why it keeps working as the network grows and why prefix-list filtering does not.

Three practical points carry most of the value. Tag from the first boundary, before a second one exists, so adding the second is purely additive. Apply the identical maps at every boundary — one untagged boundary reintroduces the problem for everything crossing it. And test by failing each boundary in turn, because a scheme that is complete on the active path and missing on the standby one behaves perfectly until the day it matters. Build the loop in a lab first; watching a traceroute alternate between two routers is worth more than any explanation of why it does.

Reference Notes

  1. Cisco, "Redistributing Routing Protocols" — mutual redistribution at two or more points can create routing loops through administrative distance interaction.
  2. Cisco, "Redistributing Routing Protocols" — route tagging as the recommended loop-prevention mechanism for multi-point redistribution.
  3. Cisco, "What Is Administrative Distance?" — default distances: connected 0, static 1, eBGP 20, EIGRP internal 90, OSPF 110, IS-IS 115, RIP 120, EIGRP external 170, iBGP 200.
  4. Cisco, "What Is Administrative Distance?" — administrative distance is compared before metric, and across protocols metric is not comparable.
  5. RFC 2328, Section 12.4.4 — the AS-external-LSA format including the 32-bit External Route Tag, which OSPF carries without interpreting.
  6. RFC 2328, Section 16.4 — external route calculation; OSPF assigns the same administrative preference to internal and external routes on Cisco platforms.
  7. RFC 7868, Section 5.7 — the EIGRP external route TLV, carrying the originating protocol, external metric, and a 32-bit administrator tag.
  8. RFC 2453, Section 4 — the RIPv2 Route Tag field, 16 bits, preserved and re-advertised without interpretation.
  9. Cisco IOS-XE IP Routing Configuration Guide — set tag and match tag in route-maps applied to redistribute statements.
  10. Cisco IOS-XE IP Routing Configuration Guide — distance ospf external and distance eigrp for per-protocol administrative distance adjustment.
  11. Cisco IOS-XE IP Routing Configuration Guide — the distance command with a source address and access-list, for per-source distance adjustment.
  12. Cisco IOS-XE EIGRP Configuration Guide — in named mode, distance eigrp and redistribute are configured under topology base.