OSPF MTU Mismatch: Neighbor Stuck in EXSTART, and Both Fixes

A neighbor parked in EXSTART means the DBD exchange is failing, and IP MTU mismatch is almost always why. Captured on CML with IOS XE 17.18.2: the asymmetric stuck states, the debug line that names the cause, a recipe to reproduce it, and both fixes proven all the way to FULL.

Terminal showing an OSPF neighbor stuck in EXSTART and the MTU mismatch debug line

An OSPF neighbor that sits in EXSTART or EXCHANGE and never reaches FULL is one of the few failures that tells you exactly what is wrong, if you know how to read it. Hellos are clearly getting through both ways (you made it past INIT and 2WAY, so timers, area ID, area type, subnet mask and authentication already agree). The two routers only fall over when they try to exchange Database Description packets, and in production that is almost always an IP MTU mismatch.

Every block of output below came off a two-router CML lab running Cisco IOS XE 17.18.2 on iol-xe nodes, with the break baked into the startup config: R1 on the default IP MTU of 1500, R2 forced to ip mtu 1400, OSPF area 0 over 10.0.12.0/30. You get the stuck neighbor from both sides, the debug line that names the cause, both fixes proven to FULL, and a recipe for reproducing the break yourself. For the surrounding context, the complete OSPF configuration and troubleshooting guide maps the cluster in reading order.

Short version: match the MTU. ip ospf mtu-ignore also drives the adjacency to FULL, and the lab proves it does, but it silences a symptom without touching the cause.

Why MTU Matters for OSPF

During adjacency formation, routers exchange Database Description (DBD) packets to compare their link-state databases before flooding any real LSAs. Every DBD header carries the IP MTU of the interface it was sent out of, and RFC 2328 section 10.6 requires the receiver to check that advertised value against its own outgoing interface MTU and reject the packet if the neighbor's number is larger.

This is not the failure most write-ups describe. The DBD is not dropped because it is too large to receive. Here is the packet R2 actually rejected:

*Jul 20 05:38:44.255: OSPF-1 ADJ   Et0/0: Rcv DBD from 1.1.1.1 seq 0x23E6 opt 0x52 flag 0x2 len 52  mtu 1500 state EXSTART
*Jul 20 05:38:44.255: OSPF-1 ADJ   Et0/0: Nbr 1.1.1.1 has larger interface MTU

Fifty-two bytes. That packet fits down any link on earth. R2 threw it away purely because the mtu 1500 field inside it was larger than R2's own IP MTU of 1400. It is a declared-value comparison, not a size problem, which is why a perfectly healthy path that passes large frames all day can still refuse to build an adjacency.

Once the DBD is discarded, the rest follows mechanically:

  • R2 never acknowledges the DBD it just rejected.
  • R1 assumes the packet was lost and retransmits it, forever.
  • Neither side reaches Loading, so no LSAs are exchanged and no routes are installed.
  • The adjacency parks and stays there. It does not usually flap, which separates it from a duplicate OSPF router ID bouncing adjacencies.

The failure lives entirely inside one packet type, so what each OSPF adjacency state actually means and what a DBD packet carries on the wire are worth reading alongside this.

What This Was Captured On

Two routers, one cable, nothing else in the way, so there is nowhere for the fault to hide.

PlatformCML, 2 x iol-xe nodes, Cisco IOS XE 17.18.2
LinkR1 Et0/0 to R2 Et0/0, back to back
Addressing10.0.12.0/30, R1 .1 and R2 .2
Router IDsLo0 1.1.1.1 on R1, 2.2.2.2 on R2
OSPFProcess 1, area 0, both interfaces plus loopbacks
The breakR2 Et0/0 has ip mtu 1400, R1 stays on the 1500 default

Symptoms of MTU Mismatch

Stuck in ExStart or Exchange State

The headline symptom is a neighbor that comes up, sticks, and never completes. What almost nobody mentions is that the two ends do not show the same state. R1, the side with the larger MTU:

R1# show ip ospf neighbor
Neighbor ID     Pri   State           Dead Time   Address         Interface
2.2.2.2           1   EXCHANGE/DR     00:00:35    10.0.12.2       Ethernet0/0

And R2, the side with the smaller MTU, at the same moment:

R2# show ip ospf neighbor
Neighbor ID     Pri   State           Dead Time   Address         Interface
1.1.1.1           1   EXSTART/BDR     00:00:39    10.0.12.1       Ethernet0/0

That asymmetry is a free diagnostic. R2 rejects R1's DBD and cannot leave EXSTART. R1 accepts R2's smaller DBD (a smaller advertised MTU passes the check), moves to EXCHANGE, then waits for an ack that never arrives. The router sitting in EXSTART is the one with the smaller IP MTU, so that single word tells you which end to go and look at.

The detailed view on R1 shows the stall as a number rather than a state:

R1# show ip ospf neighbor 2.2.2.2
 Neighbor 2.2.2.2, interface address 10.0.12.2, interface-id 2
    In the area 0 via interface Ethernet0/0
    Neighbor priority is 1, State is EXCHANGE, 4 state changes
    DR is 10.0.12.2 BDR is 10.0.12.1
    Options is 0x52 in DBD (E-bit, L-bit, O-bit)
    Dead timer due in 00:00:39
    Neighbor is up for 00:01:37
    Index 1/1/1, retransmission queue length 1, number of retransmission 11

Eleven retransmissions in a minute and thirty-seven seconds, with a queue that never drains. Run that command twice, thirty seconds apart: if number of retransmission climbs while State does not move, you have a packet the neighbor is refusing, not a packet being lost. Related failures worth knowing apart from this one: what each OSPF neighbor state tells you, why an OSPF neighbor never appears at all, and an OSPF neighbor stuck in INIT with a one-way hello when only one side can see the other.

Debug Output Shows Retransmissions

Run debug ip ospf adj on the side sitting in EXSTART. This is the whole diagnosis in one screen:

R2# debug ip ospf adj
*Jul 20 05:38:44.251: OSPF-1 ADJ   Et0/0: Send DBD to 1.1.1.1 seq 0x23E6 opt 0x52 flag 0x7 len 32
*Jul 20 05:38:44.251: OSPF-1 ADJ   Et0/0: Retransmitting DBD to 1.1.1.1 [1]
*Jul 20 05:38:44.255: OSPF-1 ADJ   Et0/0: Rcv DBD from 1.1.1.1 seq 0x23E6 opt 0x52 flag 0x2 len 52  mtu 1500 state EXSTART
*Jul 20 05:38:44.255: OSPF-1 ADJ   Et0/0: Nbr 1.1.1.1 has larger interface MTU
*Jul 20 05:38:48.801: OSPF-1 ADJ   Et0/0: Send DBD to 1.1.1.1 seq 0x23E6 opt 0x52 flag 0x7 len 32
*Jul 20 05:38:48.801: OSPF-1 ADJ   Et0/0: Retransmitting DBD to 1.1.1.1 [2]
*Jul 20 05:38:48.804: OSPF-1 ADJ   Et0/0: Nbr 1.1.1.1 has larger interface MTU
*Jul 20 05:38:53.332: OSPF-1 ADJ   Et0/0: Retransmitting DBD to 1.1.1.1 [3]
*Jul 20 05:38:53.336: OSPF-1 ADJ   Et0/0: Nbr 1.1.1.1 has larger interface MTU
*Jul 20 05:38:58.197: OSPF-1 ADJ   Et0/0: Retransmitting DBD to 1.1.1.1 [4]
*Jul 20 05:38:58.200: OSPF-1 ADJ   Et0/0: Nbr 1.1.1.1 has larger interface MTU
*Jul 20 05:39:03.134: OSPF-1 ADJ   Et0/0: Retransmitting DBD to 1.1.1.1 [5]
*Jul 20 05:39:03.137: OSPF-1 ADJ   Et0/0: Nbr 1.1.1.1 has larger interface MTU

Three things to take from that. "Nbr 1.1.1.1 has larger interface MTU" is IOS handing you the answer in plain English, so this is the first command to run, not the last. The mtu 1500 field on the Rcv DBD line is the neighbor's configured IP MTU read straight off the wire, so you can learn the far end's value without logging into it. And the retransmit counter climbing 1 through 5 on a five-second cadence is the same stall the neighbor detail view counted, seen from the other side.

Detecting MTU Mismatch

Check the Running Config, and Know Its Blind Spot

The obvious move is to compare both interfaces. Here they are:

R1# show run interface Ethernet0/0
interface Ethernet0/0
 ip address 10.0.12.1 255.255.255.252
end

R2# show run interface Ethernet0/0
interface Ethernet0/0
 ip address 10.0.12.2 255.255.255.252
 ip mtu 1400
end

Note what is not on R1. There is no ip mtu 1500 line, because 1500 is the default and IOS does not display defaults. So if you grep both configs for "mtu" and get exactly one hit, that is not a clean bill of health for the other end, it is the mismatch. "There is no MTU config on my side" is precisely what this fault looks like from the 1500 end, which is why it survives so many remote hands calls.

Why "show interface | include MTU" Will Not Find It

The single most common false negative on this fault. Look at R2 while it is broken:

R2# show interface Ethernet0/0 | include MTU
  MTU 1500 bytes, BW 10000 Kbit/sec, DLY 1000 usec,

That is R2, the router refusing DBDs because its IP MTU is 1400, reporting MTU 1500 bytes. show interface gives you the layer 2 interface MTU, the largest frame payload the interface will handle. ip mtu is a separate layer 3 knob capping the IP packets the router will originate or forward out of that interface, and it is the one OSPF advertises in the DBD. Setting ip mtu 1400 does not touch the L2 number, so this command matched on both ends while OSPF was completely broken. Use show run interface and debug ip ospf adj as your source of truth.

Test with Ping

A DF-bit ping is still worth having in your kit, as long as you are clear about what it proves:

R1# ping 10.0.12.2 size 1500 df-bit
R1# ping 10.0.12.2 size 1400 df-bit

This tests whether the forwarding path can carry a packet of that size without fragmentation, which catches a provider link that silently clips frames and makes a good pre-flight check on a new circuit. What it does not do is read the value OSPF compares. The L2 MTU here was 1500 on both ends the entire time the adjacency was down, so a path test can come back clean while the DBD check keeps failing. Finding path MTU with a DF-bit ping covers the sizing. Ping to characterise the path, debug to diagnose OSPF.

Reproduce It Yourself in Five Minutes

Build it once and you will recognise it instantly forever. Two routers, one link, OSPF area 0 on a /30, brought up healthy first.

  1. Confirm the adjacency is FULL on both ends before you touch anything.
  2. On one router only: interface Ethernet0/0, then ip mtu 1400.
  3. Check the neighbor again. Still FULL. The MTU check only runs during the DBD exchange, so an established adjacency survives an MTU change underneath it.
  4. Force a renegotiation with shutdown then no shutdown on that interface (clear ip ospf process works too).
  5. Wait. On a two-router broadcast segment there is a roughly 40 second window after the link comes up where both sides sit in 2WAY/DROTHER waiting out the DR election timer, before EXSTART is even attempted. That is normal, not the bug.
  6. Past the DR wait, show ip ospf neighbor on both ends. One shows EXSTART, the other EXCHANGE, and they stay that way.

Step 3 is the production lesson. Somebody sets an MTU on a Friday, the network keeps working, and the adjacency does not fail until the interface flaps or the router reloads weeks later, by which point nobody connects the outage to the change.

Fixes for MTU Mismatch

Both of these were run in the lab and both produced a FULL adjacency. They are not equivalent.

Solution 1: Match the MTU Values (Preferred)

Remove the odd value out and put both ends on the same number. On R2 that meant dropping back to the default, then bouncing the interface so the DBD exchange runs again:

R2(config)# interface Ethernet0/0
R2(config-if)#  no ip ospf mtu-ignore
R2(config-if)#  no ip mtu
R2(config-if)#  shutdown
R2(config-if)#  no shutdown

After the DR election and DBD exchange, roughly 40 to 60 seconds:

R2# show ip ospf neighbor
Neighbor ID     Pri   State           Dead Time   Address         Interface
1.1.1.1           1   FULL/DR         00:00:31    10.0.12.1       Ethernet0/0

R2# show run interface Ethernet0/0
interface Ethernet0/0
 ip address 10.0.12.2 255.255.255.252
end                                     <-- no 'ip mtu' line = default 1500, matching R1

R2# show interface Ethernet0/0 | include line protocol|MTU
Ethernet0/0 is up, line protocol is up
  MTU 1500 bytes, BW 10000 Kbit/sec, DLY 1000 usec,

FULL, with both ends genuinely agreeing on 1500. If the correct value for your link is not the default (a tunnel, a provider handoff), set the same explicit ip mtu on both ends instead of removing it from one.

Solution 2: ip ospf mtu-ignore (Workaround)

This tells OSPF to skip the DBD MTU check entirely. In the lab it was applied to R2 alone, the side doing the rejecting:

R2(config)# interface Ethernet0/0
R2(config-if)#  ip ospf mtu-ignore

About fifteen seconds later, from both directions:

R1# show ip ospf neighbor
Neighbor ID     Pri   State           Dead Time   Address         Interface
2.2.2.2           1   FULL/DR         00:00:36    10.0.12.2       Ethernet0/0

R2# show ip ospf neighbor
Neighbor ID     Pri   State           Dead Time   Address         Interface
1.1.1.1           1   FULL/BDR        00:00:38    10.0.12.1       Ethernet0/0

It only needed to be on the rejecting side, since that was the only end failing the check (configure both ends anyway, so the behaviour is obvious to the next engineer). It also converged faster than the matched-MTU fix, roughly fifteen seconds against forty to sixty, because no interface bounce and no fresh DR election were involved. Speed of recovery is not evidence of a better fix.

Which One Should You Actually Use?

Use Solution 1 in production. Reach for Solution 2 only when the far end is genuinely not yours to configure (a provider handoff, a multi-vendor segment that counts MTU differently) or as triage at 3am.

Match the IP MTU
AdjacencyFULL (proven)
Convergence40 to 60s (needs bounce)
Data planeConsistent both ends
Fixes the causeYes
Use itAlways, unless blocked
ip ospf mtu-ignore
AdjacencyFULL (proven)
Convergence~15s, no bounce
Data planeStill mismatched
Fixes the causeNo, hides it
Use itProvider link, or triage

"It reached FULL" is a tempting place to stop, but the MTU check exists for a reason. Once the adjacency is up, the two routers flood LSAs, and an update carrying a large database can be big. With mtu-ignore set and the mismatch still in place you can get an adjacency that reaches FULL and then fails to synchronise its database, because the oversized update never crosses. That is far uglier than a neighbor honestly parked in EXSTART: routes on one router and not the other, intermittently, with a neighbor table insisting everything is fine.

The mismatch also does not care that you told OSPF to ignore it. Traffic larger than the smaller MTU still gets fragmented or dropped, and with DF set you get the classic "ping works, SSH works, file transfers hang" black hole that gets blamed on the storage team for a fortnight. You are trading a loud control-plane failure for a quiet data-plane one, so trade deliberately, and put a ticket in to remove it.

Solution 3: ip mtu Versus mtu

These two commands look almost identical and do very different things:

R1(config-if)# ip mtu 1400     ! caps IP packets only, what OSPF advertises in the DBD
R1(config-if)# mtu 1400        ! changes the L2 interface MTU, affects every protocol

The lab proves the difference: R2 had ip mtu 1400 configured and show interface still reported MTU 1500, because only the L3 cap moved. On IOS, lowering the L2 mtu pulls the IP MTU down with it, but not the reverse. Use ip mtu to constrain IP (and therefore OSPF) without disturbing anything else on the interface, which is the normal case for tunnels. Use mtu when the link itself cannot carry standard frames, or when you are enabling jumbo frames end to end.

Common MTU Mismatch Scenarios

GRE and Other Tunnels

GRE adds 24 bytes of overhead, so a tunnel over a 1500-byte interface has an effective MTU of 1476, and IPsec on top drops it further depending on the transform set. Tunnels are where this bug actually lives, because it is easy to set the value on one end and forget the other:

interface tunnel 0
 ip mtu 1476
 ip ospf mtu-ignore     ! only if the far end genuinely cannot be adjusted

Set the same ip mtu on both tunnel interfaces and you never need the second line. Working out the right MTU for a GRE tunnel covers the arithmetic and the MSS clamping that goes with it.

Metro Ethernet and Provider Handoffs

Carriers add their own tags (Q-in-Q, MPLS labels, 4 to 8 bytes or more) and some reduce your usable MTU without telling you. Get the supported value in writing, verify it with a DF-bit ping, then enable the routing protocol. This is also where mtu-ignore is most defensible, because the far end is not yours to configure.

Jumbo Frames Half-Deployed

One device configured for 9000-byte frames, its neighbor left on 1500. Jumbo frames only work if everything in the path agrees, so roll it out across the whole segment or not at all. A half-finished jumbo deployment gives you exactly the EXSTART stall above plus a data plane that works for small packets and fails for large ones.

Verification After Fix

Two commands close this out. Both ends reach FULL, and (more important) routes actually arrive, which proves the database exchange completed rather than just that the state machine advanced:

R1# show ip ospf neighbor
Neighbor ID     Pri   State           Dead Time   Address         Interface
2.2.2.2           1   FULL/DR         00:00:36    10.0.12.2       Ethernet0/0

R1# show ip route ospf
      2.0.0.0/32 is subnetted, 1 subnets
O        2.2.2.2 [110/11] via 10.0.12.2, 00:00:27, Ethernet0/0

R2's loopback is in R1's table via the link that was broken a minute earlier. Confirm number of retransmission has stopped climbing, then finish with a DF-bit ping at your standard size so the data plane agrees with the control plane. If the neighbor is FULL but prefixes are still missing, why OSPF routes do not appear in the routing table picks up the trail.

Common Mistakes and Gotchas

  • Calling it too early. Roughly 40 seconds of 2WAY/DROTHER DR-wait is normal after the link comes up. Let the election finish before you diagnose anything.
  • Grepping both configs for "mtu" and finding one hit. IOS hides defaults, so no ip mtu line means 1500, not "unconfigured and therefore fine".
  • Trusting show interface | include MTU. It reports the L2 MTU. Here it said 1500 on the router rejecting DBDs because of an IP MTU of 1400.
  • Checking only one router. The ends show different states, and the useful one (EXSTART plus the "has larger interface MTU" log) is on the smaller-MTU side.
  • Changing the MTU and assuming you are done. An established adjacency does not re-run the check. Bounce the interface or clear the process, then verify.
  • Leaving mtu-ignore in after the outage. It reached FULL so it looks fixed, but the mismatch will resurface as a data-plane problem nobody links back to OSPF.

Best Practices

Standardise on one MTU and document the exceptions. 1500 across campus and core, with tunnels and provider handoffs listed explicitly, each with its calculated value and a reason. Every exception you cannot explain is a future EXSTART ticket.

Test MTU before you enable the routing protocol. A DF-bit ping at your standard size takes thirty seconds and saves an hour of staring at a neighbor table.

Configure tunnel MTU in pairs. Never set ip mtu on one end of a tunnel in isolation. Treat both ends as one change.

Alert on state, not on neighbor count. A neighbor stuck in EXSTART is still in the neighbor table, so a "count of neighbors" check reports healthy. Alert on any neighbor not FULL for more than a couple of minutes.

Key Takeaways

  • EXSTART or EXCHANGE that never reaches FULL means the DBD exchange is failing. Hellos already worked, so timers, area and mask are not your problem.
  • OSPF compares the MTU value advertised inside the DBD header, not the packet size. The rejected DBD here was 52 bytes and advertised mtu 1500.
  • The ends show different states. The router in EXSTART has the smaller IP MTU and logs "Nbr x.x.x.x has larger interface MTU".
  • show interface | include MTU shows the L2 MTU and will match on both ends while OSPF is broken. Use show run interface and the debug instead.
  • Both fixes reach FULL, but only matching the IP MTU is a fix. ip ospf mtu-ignore trades a visible control-plane failure for an invisible data-plane one.
  • Changing the MTU on a live adjacency does nothing until the interface bounces, which is why this shows up long after the change that caused it.

Verified in the lab on Cisco IOS XE 17.18.2 (iol-xe on CML), 2026-07-20. The rest of the series is indexed in the OSPF reading path from the ground up.

Keep Going

The neighbor never appears at all
Everything that stops a neighbor forming before EXSTART is ever reached.
Stuck in INIT, one-way hello
Hellos arrive but your router is not listed in them. The step before this one.
What every neighbor state means
DOWN through FULL, and which failure each state points at.
Duplicate router ID and flapping adjacencies
The other classic adjacency fault, and the one that bounces instead of sticking.

Read next