Table of Contents
An LDP neighbor showing "down" is one of those MPLS problems that can stem from several completely different layers — IGP reachability, a UDP discovery mismatch, a blocked TCP session, or a targeted-versus-link-local configuration mismatch. Because the symptom looks identical regardless of cause, working through the right layers in the right order is what separates a five-minute fix from an hour of guessing. This guide walks through a systematic troubleshooting workflow, compares the two LDP discovery mechanisms, digs into the transport-layer issues that trip people up most, and closes with a full verification command reference across Cisco and Juniper.
Troubleshooting an LDP Neighbor Down: The Systematic Workflow
LDP session establishment happens in two distinct phases — UDP-based discovery, then a TCP-based session — and knowing which phase is failing narrows the cause dramatically.
- Confirm IGP reachability between the two routers first. LDP relies entirely on the underlying IGP (OSPF, IS-IS, etc.) for reachability to the neighbor's transport address — if the IGP itself doesn't have a route to that address, LDP has no chance of establishing a session regardless of anything else being correctly configured.
router# show ip route <neighbor-transport-address>
- Check whether LDP discovery (Hello) is happening at all. LDP Hello packets are sent via UDP to port 646, either as link-local multicast (for directly connected neighbors) or as targeted unicast (for non-directly-connected neighbors) — confirm Hellos are being seen before assuming the problem is deeper in the TCP session.
router# show mpls ldp discovery
- Check the current LDP neighbor/session state. This tells you not just whether the session is up or down, but often the specific reason, if the platform surfaces one.
router# show mpls ldp neighbor
- Determine whether the failure is at discovery (UDP) or session (TCP) stage. If discovery shows the neighbor but the session never establishes, the problem is almost certainly TCP port 646 connectivity or a transport address mismatch — covered in depth in the next section. If discovery itself shows nothing, the problem is more likely IGP reachability, interface-level LDP enablement, or a mismatched Hello interval/hold time.
- Confirm LDP is actually enabled on the correct interface. A surprisingly common cause of "no discovery at all" is simply forgetting to enable LDP on the interface facing the neighbor, especially after an interface was reconfigured or replaced.
router# show mpls interfaces
- Check for a label distribution protocol mismatch. Confirm both routers are actually running LDP (rather than one running the legacy Tag Distribution Protocol, or a mismatched RSVP-TE-only configuration) — an obvious check, but one worth confirming explicitly rather than assuming.
router# show mpls ldp parameters
- Check for MTU-related session instability. Similar to other control-plane protocols, an MTU mismatch across the link can cause LDP sessions to flap rather than simply fail to establish — if the session comes up briefly and drops repeatedly rather than never forming at all, suspect this before deeper configuration issues.
router# show interfaces <interface> | include MTU
- Re-verify after each change, one variable at a time. As with most control-plane troubleshooting, changing multiple things simultaneously makes it much harder to know what actually fixed the problem — confirm neighbor state after each individual adjustment.
router# show mpls ldp neighbor detail
This layered approach — IGP reachability, then discovery, then session establishment — mirrors how LDP itself builds a relationship, which is exactly why working through it in this order consistently narrows down the cause fastest.
Targeted LDP vs. Link-Local LDP: Key Structural Differences
Not every LDP neighbor relationship is discovered the same way, and knowing which type you're dealing with changes what you should check first.
| Criteria | Link-Local (Basic) LDP | Targeted LDP |
|---|---|---|
| Discovery mechanism | UDP multicast Hello sent directly on a shared link | UDP unicast Hello sent to a specific, often non-directly-connected, address |
| Typical use case | Directly connected MPLS-enabled links between adjacent routers | Non-directly-connected neighbors, such as across a Layer 2 access network, for pseudowire/VPLS setups, or session backup/redundancy scenarios |
| Configuration requirement | Usually automatic once LDP is enabled on the interface | Requires explicit configuration specifying the target neighbor's address |
| Dependency on IGP | Relies on IGP only for the transport address resolution used during TCP session setup, not for Hello delivery itself (which is link-local) | Relies fully on IGP reachability for both Hello delivery (since it's unicast, routed) and transport address resolution |
| Common failure mode | Interface-level misconfiguration (LDP not enabled), or a directly connected Layer 1/2 issue | Missing or incorrect target address configuration, or a routing path failure between the two non-adjacent routers |
| Diagnostic starting point | Confirm LDP is enabled on the correct interface first | Confirm the targeted neighbor statement is present and the address is reachable via the IGP first |
| Common Cisco config command | mpls ip on the interface |
mpls ldp neighbor <address> targeted |
The practical distinction that matters most for troubleshooting: a link-local LDP failure is almost always a Layer 1/2 or interface-configuration problem local to that link, while a targeted LDP failure is almost always a routing (IGP) or explicit-configuration problem — start your investigation in the layer that matches which type of session you're actually dealing with.
Transport Address Mismatches and TCP Port 646 Failures
When LDP discovery succeeds but the session never actually establishes, the problem has moved from the UDP discovery phase into the TCP session phase — and this is where transport address and connectivity issues live.
- Understand what the LDP transport address actually is. After discovery, LDP routers use a specific IP address — typically a loopback interface by default — to establish the actual TCP session on port 646. This transport address is advertised within the Hello packet itself.
- Recognize the classic transport address mismatch scenario. If one router's advertised transport address isn't reachable from the other router (for example, its loopback isn't being advertised into the IGP, or is filtered), discovery can succeed via a directly connected interface while the TCP session fails, since the session attempt targets an address that can't actually be reached.
- Verify the transport address being advertised.
router# show mpls ldp discovery detail
- Confirm the advertised transport address is reachable via the IGP. This is the single most common root cause of "discovery works, session doesn't" — check specifically for the transport address, not just the interface's directly connected address.
router# show ip route <advertised-transport-address>
- Check for an access list or firewall blocking TCP port 646. Unlike the UDP Hello packets, the LDP session itself is TCP-based, so a stateful firewall or ACL that permits UDP 646 but blocks TCP 646 (or vice versa) will produce exactly this "discovery succeeds, session fails" pattern.
router# show access-lists
router# show ip access-lists interface <interface>
- Confirm the TCP session state directly if available on your platform. Some platforms expose LDP's underlying TCP connection state directly, which can confirm whether the router is even attempting the TCP handshake.
router# show tcp brief | include 646
- Fix a transport address mismatch by aligning IGP advertisement. If the issue is that a loopback used as the transport address isn't in the IGP, the fix is typically to ensure that loopback is included in the IGP's network statements or redistribution, or to explicitly configure LDP to use a different, already-reachable interface as its transport address.
router(config)# mpls ldp router-id <interface> force
- Fix a blocking ACL by explicitly permitting TCP port 646 between the two routers. Make sure any ACL applied to the relevant interface allows both the UDP discovery traffic and the TCP session traffic — a common mistake is fixing one and forgetting the other.
router(config)# ip access-list extended LDP-PERMIT
router(config-ext-nacl)# permit tcp host <router-a-ip> host <router-b-ip> eq 646
router(config-ext-nacl)# permit udp host <router-a-ip> host <router-b-ip> eq 646
- Re-verify the full session state after resolving transport or ACL issues. Confirm the session moves from a discovery-only state to a fully established neighbor relationship, not just that traffic is no longer being blocked.
router# show mpls ldp neighbor detail
Once the transport address is confirmed reachable via the IGP and any ACLs or firewalls explicitly permit both UDP and TCP traffic on port 646, LDP sessions that were stuck at the discovery stage almost always complete and move to established state without further intervention.
LDP Neighbor Troubleshooting Command Cheat Sheet: Cisco and Juniper
For quick reference during troubleshooting, here's a consolidated command set covering discovery, session state, transport address, and platform-specific syntax across both major vendors.
# --- Cisco IOS/IOS-XE: Discovery and neighbor state ---
router# show mpls ldp discovery # Hello-based discovery status
router# show mpls ldp discovery detail # Includes advertised transport address
router# show mpls ldp neighbor # Current neighbor/session state
router# show mpls ldp neighbor detail # Full session detail including timers
# --- Cisco IOS/IOS-XE: Interface and parameters ---
router# show mpls interfaces # Confirm LDP enabled per interface
router# show mpls ldp parameters # Global LDP configuration/session parameters
router(config-if)# mpls ip # Enable LDP on an interface (link-local)
router(config)# mpls ldp neighbor <address> targeted # Configure targeted LDP session
router(config)# mpls ldp router-id <interface> force # Set explicit transport/router ID
# --- Cisco IOS/IOS-XE: Transport and connectivity checks ---
router# show ip route <transport-address> # Confirm IGP reachability
router# show access-lists # Check for blocking ACLs
router# show tcp brief | include 646 # Check TCP session state directly
# --- Juniper Junos: Discovery and neighbor state ---
> show ldp neighbor # Current neighbor/discovery state
> show ldp session # TCP session state and detail
> show ldp session detail # Full session parameters
> show ldp interface # Confirm LDP enabled per interface
> show ldp database # Label bindings learned
# --- Juniper Junos: Configuration ---
# set protocols ldp interface <interface-name> # Enable LDP on an interface
# set protocols ldp session <neighbor-address> # Configure targeted session
# set protocols mpls interface <interface-name> # Enable MPLS on an interface
# --- Cross-platform packet capture (last resort) ---
router# debug mpls ldp transport events # Cisco: TCP transport events
router# debug mpls ldp messages # Cisco: Hello/session message exchange
Keep the "discovery detail" and transport-address reachability checks near the top of your workflow — in both Cisco and Juniper environments, that combination diagnoses the large majority of LDP neighbor-down cases faster than reaching for debug output.
