OSPF Deep Dive Part 10: A Vendor-Neutral Troubleshooting Methodology
Parts 7 through 9 covered how CORE-CSR, BRANCH-FGT, and EDGE-MX each implement OSPF differently. This post is deliberately vendor-neutral again, because the actual troubleshooting logic doesn’t change across platforms. What changes is only the command used to look at the same underlying state, which Part 11 covers directly. This post is the reasoning that decides which command to reach for in the first place.
Start below OSPF, not inside it
Before touching anything OSPF-specific, confirm the interface is actually up at Layer 1 and Layer 2, and that basic IP reachability exists between the two routers’ interface addresses. This sounds obvious enough to skip, and skipping it is exactly how people end up debugging authentication configuration for twenty minutes on a link where the actual problem is a bad SFP or a mismatched VLAN. OSPF runs over IP protocol 89 directly, no TCP or UDP port, which also means a stateful firewall or ACL between two would-be neighbors has to explicitly permit protocol 89 rather than a familiar port number, and a silently dropped protocol-89 packet produces exactly the same symptom as a hello-parameter mismatch: no neighbor relationship ever forms, with nothing in either router’s OSPF process to explain why, because from OSPF’s perspective no hello ever arrived.
The one question that organizes everything else
Once basic reachability is confirmed: what state is the neighbor stuck at, and has it been stuck there consistently, or is it flapping? Part 1 laid out the full state machine for exactly this reason. Every stuck state rules out an entire category of causes and points at a much smaller remaining set.
| Stuck at | What’s ruled out | What to actually check |
|---|---|---|
| No neighbor entry at all (stuck at or below Down) | Nothing OSPF-specific has happened yet | L1/L2 reachability, protocol 89 permitted end to end, correct subnet/mask on both sides |
| Init | The far end’s hello is arriving, but this router’s hello isn’t reaching it, or isn’t listing the far end back | Asymmetric ACL or routing, one-way multicast delivery, hello/dead timer or area ID mismatch on the return path |
| 2-Way and staying there | Full adjacency was expected but this is a DROTHER-to-DROTHER relationship on a broadcast/NBMA segment | Confirm this is actually expected given the DR/BDR election from Part 1, not assumed to be broken; check priority 0 or election history if a specific router should have become DR and didn’t |
| ExStart or Exchange | Hello-level parameters already agree, since the routers got this far | MTU mismatch (the leading cause by far), duplicate router-ID between the two neighbors or elsewhere in the area, or a rare master/slave negotiation failure |
| Loading, not progressing to Full | Both routers agree on what’s missing from each other’s database | Packet loss or retransmission on the link itself, since Loading is where actual LSA payloads move, not just headers |
| Full, but routes are missing or unexpected | The adjacency itself is healthy | This is not a neighbor-state problem at all; move to the LSDB and area-type checks below |
Authentication mismatches from Part 6 and area-ID/timer mismatches from Part 1 both manifest identically: no neighbor relationship progresses past Down, because a hello that fails any of those checks is discarded before the state machine advances at all, not held in a partially-failed state. This is worth internalizing on its own, because it means “no neighbor showing up” is actually a large bucket covering several distinct root causes that all look the same from the outside, and distinguishing between them requires comparing the actual hello parameters configured on both sides rather than inferring the cause from the symptom alone.
Duplicate router-ID deserves its own callout
A duplicate router-ID, two routers in the same OSPF domain both using, say, 10.0.0.2, doesn’t behave like a clean failure. It can let an adjacency form and reach Full while producing inconsistent or flapping entries in the LSDB, since Type 1 LSAs are keyed by originating router-ID and two different physical routers claiming the same one corrupts the database’s ability to tell them apart. Symptoms include routes that intermittently disappear and reappear, self-originated-LSA warnings on a router that didn’t actually originate the conflicting LSA, and SPF recalculating far more often than the topology’s actual stability would suggest. This is exactly why Part 1 flagged duplicate router-ID as a cause of ExStart/Exchange trouble specifically, but it’s worth restating that a duplicate ID’s damage isn’t limited to the two routers directly involved; it degrades the whole area’s LSDB consistency.
Full adjacency with wrong routes is a different investigation entirely
Once a neighbor reaches Full, the state machine from Part 1 is no longer the relevant model. The LSDB is now synchronized (correctly, barring the duplicate router-ID case above), and any routing problem from this point is either an area-type filtering behaving exactly as configured but not as intended, revisit Part 2’s table of what stub, totally stubby, and NSSA actually block, a summarization boundary hiding more specific routes than expected, revisit Part 4, or a route-preference issue from a completely different protocol winning over OSPF for the same prefix, which Part 9’s Junos preference-ordering gotcha is the sharpest example of in this series, but applies just as much to a static route or a competing dynamic protocol on any of the three platforms.
The practical habit this suggests: before assuming OSPF itself is broken when routes look wrong, confirm the adjacency state first (Full, and has been for a while, not flapping), then confirm the LSDB actually contains the expected LSA for the missing prefix, and only conclude OSPF is misbehaving if the correct LSA is present in the LSDB but still isn’t making it into the routing table. That last case almost always means something outside OSPF, redistribution filtering, route-map/policy denial, or administrative distance and preference, is the actual cause, and Part 9’s Junos example shows exactly how a correctly functioning OSPF domain can still lose a route to a completely unrelated protocol’s default preference.
Part 11 puts this methodology into practice with the actual commands: neighbor tables, interface state, and LSDB contents, read side by side across Cisco, FortiOS, and Junos.