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

MPLS LDP: The Session Is Up, the Routing Is Perfect, and Nothing Is Label Switched

Label distribution is the quietest part of an MPLS network and the part that fails in the most confusing way. When it breaks, the routing protocol stays up, every neighbour is present, every prefix is in the routing table, and traffic that should be label switched either takes a path nobody intended or disappears entirely. Nothing in the output of the commands people habitually run says anything is wrong.

The reason is that labels are distributed by a protocol that runs alongside the routing protocol and depends on it without being part of it. LDP learns where to send hellos from the interface configuration, learns which prefixes deserve labels from the routing table, and learns how to reach its neighbour's transport address from the routing protocol again. Three dependencies, each of which can be satisfied while the one above it fails, which is why the failures are quiet.

This article covers how LDP finds a neighbour and builds a session, which labels it advertises and to whom, where the label tables come from and how to read them, why a session can be up while forwarding is broken, and a fixed troubleshooting order that turns a vague complaint into a specific answer in six commands. It is written for the lab rather than for the written exam, and sits alongside the rest of the CCIE Enterprise Infrastructure lab certification track.

Blog ClaimNearly every LDP fault is one of three things — a transport address the neighbour cannot reach, a prefix that never had a label because of how it was learned, or an IGP that converged before labels existed — and not one of the three is visible in the routing table.
LDP builds in four stages and each one depends on the stage before it while being separately configurable, which is why a failure at one stage leaves every check at the others looking healthy.

How Does LDP Find a Neighbour and Build a Session?

What are the two stages?

Discovery, then session. Discovery is UDP hellos on port 646 — multicast to all routers on an interface that has MPLS enabled, or unicast to a configured address for a neighbour that is not adjacent. Discovery only proves the two routers can hear each other. The session is a separate TCP connection on port 646, made not to the interface address but to the transport address each router advertised in its hellos. That distinction is where most session failures live: hellos arrive, the transport address is unreachable, and the session never forms.

A Deeper Dive into Discovery and Sessions

Two kinds of hello, for two kinds of neighbour

A link hello is sent because an interface has MPLS forwarding enabled. It goes to the all-routers multicast address with a TTL of one, so it reaches the directly connected neighbour and no further. This is the ordinary case and needs no configuration beyond enabling MPLS at both ends of the link.

A targeted hello is unicast to a specific address and is sent because something asked for it — an explicit targeted neighbour statement, or a feature such as session protection that creates one on its own. It can traverse several hops, which is what makes it useful for keeping a session alive between routers that are not adjacent, or between routers whose direct link has just gone down but which remain reachable another way.

The distinction matters when reading output. A neighbour that appears with a targeted source is not using the link you think it is, and a neighbour that disappears when a link fails was a link neighbour rather than a targeted one. Both facts are visible in the discovery output and neither is visible in the neighbour summary.

! Link discovery: just enable forwarding on the interface
P1(config)# interface GigabitEthernet0/1
P1(config-if)# mpls ip
!
! Or enable it everywhere the IGP runs, which is usually what is wanted
P1(config)# router ospf 1
P1(config-router)# mpls ldp autoconfig area 0
!
! Targeted, for a neighbour that is not adjacent
P1(config)# mpls ldp neighbor 10.255.0.9 targeted

The transport address, which is where sessions fail

Each router advertises a transport address inside its hellos, and the TCP session is built to that address rather than to the interface the hellos arrived on. By default that address is the LDP router identifier, which is normally a loopback. The consequence is direct and frequently missed: the two routers must have a route to each other's loopback before a session can form, even though they are directly connected and the hellos are arriving perfectly.

In a network where the IGP is already running this is usually satisfied without anyone thinking about it. It stops being satisfied in three situations — a loopback that was never advertised into the IGP, a loopback that is covered by a summary rather than being a host route, and a stage of a build where MPLS was configured before the IGP was complete. All three produce hellos with no session.

The transport address can be changed to the interface address, which removes the dependency entirely. That is a reasonable choice on a link where no loopback exists, and a poor one generally, because the session then dies with the interface rather than surviving a reroute.

Pitfall: hellos are exchanged and no session forms Symptom: the discovery output shows the neighbour with hellos being sent and received, and the neighbour never appears in the session list. Nothing about the interface or the IGP looks wrong. Cause: the TCP session is built to the advertised transport address, not to the interface address. If there is no route to the neighbour's transport address — because its loopback is not in the IGP, or is hidden behind a summary — the connection cannot be made. Confirm: show mpls ldp discovery detail shows the transport address the neighbour advertised; try to reach it. Fix: advertise the loopback into the IGP as a host route, or set the transport address explicitly to something both routers can reach.

Who initiates, and why it matters

Only one of the two routers opens the TCP connection. The one with the numerically higher identifier takes the active role and connects; the other waits. This is not usually something anyone needs to act on, but it explains an asymmetric symptom: if a filter blocks the connection in one direction only, the session fails or succeeds depending on which router happened to have the higher identifier, which makes the failure look arbitrary across a network where the filter is applied uniformly.

Pinning the router identifier

The identifier is chosen from the available loopbacks, and the selection changes if a higher-numbered loopback is added later. Because the identifier is also the default transport address, a change to it tears down every session on the router. That is a genuinely disruptive outcome from what looked like an unrelated addition, and the reason to pin the identifier explicitly on every router in a production build rather than letting it be derived.

! Pin it. The force keyword applies the change immediately,
! which resets sessions - do it in a window.
P1(config)# mpls ldp router-id Loopback0 force
!
P1# show mpls ldp discovery detail
Local LDP Identifier: 10.255.0.1:0
  Discovery Sources:
  Interfaces:
    GigabitEthernet0/1 (ldp): xmit/recv
        Enabled: Interface config
        Hello interval: 5000 ms; Transport IP addr: 10.255.0.1
        LDP Id: 10.255.0.2:0
          Src IP addr: 10.1.12.2; Transport IP addr: 10.255.0.2
          Hold time: 15 sec; Proposed local/peer: 15/15 sec

Reading the discovery output honestly

Three fields carry all the diagnostic value. The xmit/recv state tells you whether hellos are going both ways — xmit alone means the neighbour is not sending, which almost always means MPLS is not enabled on its side of the link. The peer's transport address tells you what the TCP connection will be made to, which is the thing to test when discovery works and the session does not. And the hold time tells you how long a neighbour survives silence, which sets how long a failure takes to be noticed.

Authentication, and its asymmetry

A password can be required on an LDP session. The mechanism is the ordinary TCP authentication option rather than anything specific to LDP, which means the failure mode is a TCP connection that is refused rather than an LDP error. Discovery continues to work perfectly, because hellos are UDP and are not authenticated.

So a password configured on one router and not the other produces exactly the same symptom as an unreachable transport address: hellos both ways, no session. The two are distinguished by whether the transport address is reachable, which is why that test comes first in any session-stage investigation.

Stage Transport Port Fails when
Link discovery UDP, multicast, TTL 1 646 MPLS not enabled on one side
Targeted discovery UDP, unicast 646 No route to the targeted address
Session TCP, to the transport address 646 Transport address unreachable, or password mismatch
Advertisement Over the established session Prefix absent, or filtered
Test the transport address, not the linkWhen hellos are exchanged and no session appears, the single most useful action is to source a ping from the local loopback to the peer's advertised transport address. It succeeds and the problem is authentication or a filter; it fails and the problem is routing. One command splits the remaining possibilities in half.
Sub claimDiscovery proves the link and the session proves the routing, and because they use different transports to different addresses, a healthy discovery says nothing whatever about whether a session can form.

Which Labels Does LDP Advertise, and to Whom?

What is the advertisement model?

Every router assigns its own label to every eligible prefix in its routing table and advertises that label to every LDP peer, unasked. Peers keep what they receive even when they will not use it. The result is that a router holds several labels for the same prefix — one from each neighbour — and uses only the one received from the neighbour its routing protocol has chosen as the next hop. The unused ones are held against the day the next hop changes, which is what makes label switching reconverge as fast as the routing protocol does.

A Deeper Dive into Label Advertisement

Unsolicited advertisement, in plain terms

There is no request. A router does not ask for a label; the neighbour sends one for everything it has as soon as the session comes up, and sends updates as its routing table changes. That is more state than strictly necessary and the right trade — the alternative is a request and reply per prefix at the moment the network is least stable.

The practical consequence when reading output is that the binding table is large and mostly unused, and that is normal rather than a symptom. A prefix with four bindings on a router with four neighbours means the mechanism is working. A prefix with one binding on that same router means three neighbours did not advertise it, which is a real finding.

Which prefixes get a label

Prefixes in the routing table, learned by an interior protocol or connected or static. BGP-learned prefixes do not get labels, and that is deliberate rather than a limitation — in the designs LDP exists to support, BGP prefixes are carried end to end between edge routers and the core has no business holding labels for them.

Pitfall: a prefix in the routing table with no label binding Symptom: forwarding to one destination is not label switched while everything else on the same router is. The prefix is present and reachable. Cause: labels are assigned to prefixes learned by an interior protocol, not to BGP-learned prefixes, and not to a prefix that is only present as part of a summary. Either change removes the binding without touching reachability. Confirm: show mpls ldp bindings 10.255.0.5 32 returns nothing, while show ip route 10.255.0.5 returns a route. Fix: establish how the prefix is being learned and restore it to the interior protocol as a host route, or accept that this destination is not label switched and design around it.

The two null labels

A router advertising a label for a prefix it is directly attached to has no use for that label — it is going to look the packet up in its own routing table anyway. Rather than ask the upstream router to impose a label that will immediately be removed, it advertises implicit null, which means "send this to me with the label already removed". The upstream router pops the label and forwards. This is penultimate hop popping and it is the default.

Explicit null is the alternative: keep the label header, but with a value that carries no forwarding meaning. It exists because the label header carries quality-of-service bits that are lost when the header is popped a hop early. If class of service is being carried in those bits and enforced at the last hop, explicit null preserves them at the cost of one more label operation.

! What the far end advertised, and what we do with it
P1# show mpls ldp bindings 10.255.0.2 32
  lib entry: 10.255.0.2/32, rev 18
        local binding:  label: 2001
        remote binding: lsr: 10.255.0.2:0, label: imp-null
        remote binding: lsr: 10.255.0.3:0, label: 3005
!
! Request explicit null instead, network-wide, if EXP must survive
P1(config)# mpls ldp explicit-null

Limiting what is advertised, and to whom

Advertising a label for every prefix is fine in a core where the routing table is small and consists mostly of loopbacks and links. It is wasteful in a network carrying a large interior table, where the only prefixes that actually need labels are the edge routers' loopbacks. Filtering the advertisement to a prefix list is a legitimate scaling measure and a legitimate source of outages, because a prefix list that omits a loopback silently removes the path to it.

The same applies to restricting which peers receive an advertisement. Both controls are useful and both should be documented next to the prefix list itself, because a filter that was correct when written is the thing nobody thinks to check two years later when a new edge router is added and does not work.

! Advertise labels only for edge loopbacks
P1(config)# ip prefix-list LDP-LOOPBACKS permit 10.255.0.0/24 ge 32
P1(config)# no mpls ldp advertise-labels
P1(config)# mpls ldp advertise-labels for LDP-LOOPBACKS
!
! Confirm what is actually being advertised now
P1# show mpls ldp bindings advertisement-acl

Liberal retention, and why the tables look large

Labels received from a neighbour that is not the next hop are kept rather than discarded. The table is therefore larger than the forwarding table by roughly the number of neighbours, and that is the intended behaviour. The benefit is convergence: when the routing protocol selects a different next hop, the label for that next hop is already present and forwarding follows immediately.

A note on the label range

Labels below sixteen are reserved for special meanings, of which implicit and explicit null are the two seen in ordinary operation. Dynamic labels are drawn from a platform-defined range above that. The range can be changed, and the one good reason to change it is to make labels identifiable by router during a troubleshooting exercise — giving each router a distinct block means a label seen in a capture immediately identifies who assigned it.

What you want to know Command What it shows
Did the neighbour send a label for this prefix? show mpls ldp bindings Every label held, used or not
Which label are we actually imposing? show mpls forwarding-table The one in use, per prefix
Is MPLS on this interface at all? show mpls interfaces Per-interface forwarding state
Are hellos being exchanged? show mpls ldp discovery xmit/recv per interface
Is the session established? show mpls ldp neighbor TCP state and uptime
Sub claimHolding several labels per prefix and using one is not redundancy for its own sake — it is what allows label switching to follow an IGP reconvergence without any label signalling at all.

Where Do the Label Tables Come From, and How Do You Read Them?

How many tables are there?

Three, and conflating them is the most common reason a troubleshooting session goes in circles. The routing table decides the next hop. The binding table holds every label received for every prefix, from every neighbour, whether used or not. The forwarding table holds the single entry actually used to switch a packet — built by taking the next hop from the routing table and the label that next hop advertised, from the binding table. A missing forwarding entry is always explained by one of the two tables above it.

A Deeper Dive into the Tables

The routing table decides, the binding table supplies

This is the relationship to hold in mind. The routing protocol picks the next hop with no knowledge of labels. The binding table already contains a label from that next hop, because it contains one from everybody. The forwarding entry is the combination. Nothing negotiates, nothing is requested, and the whole thing is assembled locally from information that was already present.

Which means a forwarding entry can be missing for exactly two reasons: the routing table has no next hop, or the binding table has no label from it. Establishing which of the two applies takes two commands and eliminates every other hypothesis.

Reading the binding table

Each entry shows a local binding — the label this router assigned and advertised to everyone — and a remote binding per neighbour. The local binding is the incoming label: traffic arriving with it will be processed for this prefix. The remote bindings are candidates for the outgoing label, and only one will be chosen.

Two things are worth looking for. Whether the expected neighbour appears at all, which answers whether advertisement reached this router. And whether the label from that neighbour is a null value, which tells you this router is the penultimate hop and will be popping rather than swapping.

! Every label held for one prefix, and where each came from
P1# show mpls ldp bindings 10.255.0.5 32
  lib entry: 10.255.0.5/32, rev 44
        local binding:  label: 2044
        remote binding: lsr: 10.255.0.2:0, label: 3061
        remote binding: lsr: 10.255.0.3:0, label: 4017
!
! Which of those is actually used - the IGP decides
P1# show ip route 10.255.0.5
Routing entry for 10.255.0.5/32
  Known via "ospf 1", distance 110, metric 21
  * 10.1.12.2, from 10.255.0.5, via GigabitEthernet0/1

Reading the forwarding table

One line per prefix, showing the incoming label, the outgoing label, the prefix and the outgoing interface and next hop. The outgoing label is the one from the neighbour that the routing table selected, and it will read as a pop instruction where the neighbour advertised null.

The byte counter on each line is more useful than it looks. A forwarding entry that exists and has never incremented means the path is built and nothing is using it, which points at the upstream routers rather than at this one. An entry that is incrementing means this hop is doing its job and the investigation belongs further along.

! The entry actually used, and whether anything is hitting it
P1# show mpls forwarding-table 10.255.0.5 32
Local  Outgoing   Prefix           Bytes Label   Outgoing   Next Hop
Label  Label      or Tunnel Id     Switched      interface
2044   3061       10.255.0.5/32    184052        Gi0/1      10.1.12.2
!
! And the penultimate hop case, on the router one before the egress
P4# show mpls forwarding-table 10.255.0.5 32
Local  Outgoing   Prefix           Bytes Label   Outgoing   Next Hop
Label  Label      or Tunnel Id     Switched      interface
3061   Pop Label  10.255.0.5/32    184052        Gi0/2      10.1.45.5

When the forwarding table has no entry

Work upward. Is the prefix in the routing table, and is it a host route or part of a summary? If it is present, is there a binding from the next hop specifically — not from anybody, from that neighbour? If there is no binding from that neighbour, is there a session with it? If there is no session, is discovery working?

Four questions, each one a single command, and each answer eliminates everything below it. The reason to work in this direction rather than starting at discovery is that the first question resolves it outright more often than the other three combined.

Verifying the path rather than the hop

The tables tell you what one router will do. They do not tell you whether the whole path works, and a path is only as good as its worst hop. The label switched path can be tested directly, which sends a probe that is forwarded using the label stack rather than using ordinary IP, so a break in the label path is detected even where ordinary reachability is fine.

This is the single most valuable verification in an MPLS network, because it distinguishes "the network is broken" from "the label path is broken" conclusively, in one command, without inspecting any tables at all.

! Does the label path exist end to end?
P1# ping mpls ipv4 10.255.0.5/32
Sending 5, 100-byte MPLS Echos to 10.255.0.5/32,
     timeout is 2 seconds, send interval is 0 msec:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/2/4 ms
!
! Where does it break, and what labels are used at each hop?
P1# traceroute mpls ipv4 10.255.0.5/32

What the path test tells you that a ping does not

An ordinary ping to a loopback succeeds whenever IP routing works, label switched or not. That is the whole problem: on a network where the label path is broken and IP routing is fine, the ping succeeds and reports that everything is healthy. It is not a test of MPLS in any sense and using it as one is responsible for a lot of wasted time.

The label path test is a test of MPLS, and where it fails it reports the hop at which the label stack could not be followed. That is the answer, and everything after it is confirming a cause rather than searching for a location. Reading this once is not the same as being able to do it under time pressure, which is what repetition against realistic CCIE lab practice scenarios is for.

Three tables, three questionsRouting table: where would this go? Binding table: is there a label available from that direction? Forwarding table: what is actually being done? Asking the wrong table the right question is what makes LDP troubleshooting feel unpredictable.
Sub claimA forwarding entry is assembled locally from the routing table and the binding table, so a missing entry is always explained by one of those two and never by anything else.

Why Does a Session Come Up and Forwarding Still Fail?

What are the causes worth knowing?

Four. A destination loopback covered by a summary rather than advertised as a host route, which removes the label while leaving reachability intact. An interior protocol that converged over a link before label distribution finished on it, so traffic is sent down a path with no labels. A link that flaps and drops its session, discarding labels that would have been valid moments later. And an MTU that does not account for the label headers, which breaks large packets while everything small succeeds.

A Deeper Dive into the Quiet Failures

The summarised loopback

Summarisation is a normal and desirable thing to do at an area boundary, and it is incompatible with the assumption that every edge router's loopback is individually reachable. A label is assigned per prefix in the routing table; summarise four loopbacks into one shorter prefix and there are no longer four prefixes, so there are no longer four labels.

What makes this hard to spot is that reachability is untouched. The summary routes traffic correctly, every ping succeeds, the routing protocol is healthy by every measure. Only the label path is gone, and only the things that depend on a label path notice.

Pitfall: an area boundary summary removes the label switched path Symptom: everything that relies on end-to-end label switching between two edge routers stops working after an area boundary change, while ordinary reachability between them is unaffected and every routing check passes. Cause: labels are assigned per prefix, and a summary replaces the individual host routes with one shorter prefix. The specific prefixes no longer exist, so their labels no longer exist. Confirm: ping mpls ipv4 <loopback>/32 fails while an ordinary ping to the same address succeeds. Fix: advertise the edge loopbacks as host routes in addition to the summary, or exclude them from it. Reachability was never the problem and changing it will not help.

The interior protocol that converged first

When a link comes up, the routing protocol forms its adjacency in a second or two and label distribution takes longer — discovery, then a TCP session, then advertisement. In between, the routing protocol has installed a path over a link that cannot label switch, and traffic sent that way is dropped or falls back to unlabelled forwarding.

On a link that comes up once this is a few seconds of trouble at a moment when trouble is expected. On a link that flaps, it is a repeated, intermittent fault that correlates with nothing anybody is monitoring. The fix is synchronisation: the routing protocol advertises the link at a cost high enough to keep traffic away until the label session on it is established, then advertises the real cost.

! Do not use a link for transit until labels are ready on it
P1(config)# router ospf 1
P1(config-router)# mpls ldp sync
!
! How long to wait before giving up and using it anyway
P1(config)# mpls ldp igp sync holddown 10000
!
! Which interfaces are waiting, and which are ready
P1# show mpls ldp igp sync
    GigabitEthernet0/1:
        LDP configured; LDP-IGP Synchronization enabled.
        Sync status: sync achieved; peer reachable.

Session protection and the flapping link

When a link goes down, the session that ran over it goes down with it and every label learned across it is discarded. If the link returns a few seconds later, all of that is rebuilt from nothing. Where the two routers remain reachable by another path throughout, that teardown was unnecessary.

Session protection addresses this by establishing a targeted hello relationship alongside the link one. The session then survives the link failure as long as the neighbour is reachable somehow, the labels are retained, and when the link returns forwarding resumes without rebuilding anything. On a network with any history of flapping links this is one of the highest-value single commands available.

! Keep the session alive across a link failure
P1(config)# mpls ldp session protection
!
! Or only with specific neighbours, for a defined duration
P1(config)# mpls ldp session protection for PROTECTED-PEERS duration 300
!
P1# show mpls ldp neighbor 10.255.0.2 detail | include Protection
    LDP Session Protection enabled, state: Ready

MTU, and the packets that never come back

Each label adds four bytes. A packet that fitted exactly before labels are imposed does not fit afterwards, and because the shortfall is small, small packets are unaffected. The symptom is therefore selective: interactive traffic is fine, file transfers stall, and a ping succeeds while a ping with a large payload does not.

The correct fix is to raise the MTU on core links so that the labelled packet fits, which requires the underlying interface to support it and requires it to be consistent on both ends of every link. Setting it on one end produces a mismatch that can break the routing protocol adjacency as well, turning a subtle problem into an obvious one — which is, at least, easier to find.

Pitfall: small packets pass and large ones do not Symptom: ordinary pings succeed, sessions establish, routing is stable, and applications that transfer bulk data stall or perform terribly across the core. Cause: every imposed label adds four bytes, so a packet at the previous maximum size exceeds it once labelled. Where the oversized packet is dropped without a notification reaching the sender, the sender retransmits indefinitely. Confirm: ping with a large payload and the do-not-fragment bit set; it fails where the ordinary ping succeeded. Fix: raise the MPLS MTU on every core interface to accommodate the label stack, consistently on both ends of each link.

A filter that was meant for something else

LDP uses UDP and TCP port 646. An access list applied to a core interface for some unrelated reason, or a control plane policy that was written against a list of expected protocols, will block it without any indication that it has done so. The routing protocol continues to work because it is a different protocol on a different port, so every check anybody runs looks healthy.

This is worth including in a checklist specifically because it is invisible from the LDP side — there is no message saying a connection was refused, only a session that does not appear. Where a session fails and the transport address is demonstrably reachable, a filter is the next thing to look at rather than the last.

The routing protocol is not evidenceEvery failure in this section leaves the interior routing protocol completely healthy, because in every case the routing protocol is doing exactly what it was asked to do. Using its health as evidence that the network is fine is the single habit that makes these failures take hours instead of minutes.
Sub claimEach of these four failures leaves reachability intact, which is why an ordinary ping is not a test of an MPLS network and should never be treated as one.

How Do You Troubleshoot LDP in a Fixed Order?

What is the order?

Six steps, downward through the dependencies. Is MPLS enabled on the interface? Are hellos exchanged? Is the session established? Is there a binding for the prefix from the right neighbour? Is there a forwarding entry? Does the label path work end to end? Each step has one command and each answer eliminates everything below it, which turns an open-ended investigation into a bounded one.

A Deeper Dive into the Procedure

Step one: is forwarding enabled here at all?

The first check is whether MPLS is enabled on the interface in question, on both sides. This sounds too basic to be worth a step and it resolves a meaningful share of cases, particularly on a network where interfaces are added by different people at different times and the template was updated in between.

The output shows per-interface state and takes a second to read. Doing it first costs nothing and removes the possibility of spending twenty minutes on discovery for a link where discovery was never going to happen.

Step two: are hellos being exchanged?

Discovery output, looking at the transmit and receive state. Both directions means move on. Transmit only means the other side is not sending, which sends you to step one on that router. Nothing at all means MPLS is not enabled locally, which sends you to step one here.

Step three: is the session established?

If discovery works and there is no session, the cause is almost always the transport address. Test it by sourcing a packet from the local loopback to the address the neighbour advertised. Success moves the suspicion to authentication or a filter; failure makes it a routing problem and the investigation moves to the interior protocol.

This is the step where the largest share of genuine faults resolve, and the one most often skipped because the session state is easy to see and the reason for it is not.

Step four: is there a binding, from the right neighbour?

Not "is there a binding" — there usually is, from someone. The question is whether the neighbour that the routing table has selected as the next hop has advertised a label for this prefix. A binding from three other neighbours and not from that one produces a missing forwarding entry and looks, at a glance, like a healthy table.

Where the binding is missing from that neighbour specifically, the cause is upstream: either it has no label to give, because the prefix is summarised or BGP-learned there, or an advertisement filter is in the way.

Step five: is there a forwarding entry?

With a next hop and a binding from it, an entry should exist. Where it does, check the byte counter: zero means the path is built and unused, which points the investigation at the routers before this one rather than at this one. A non-zero and increasing counter means this hop is working.

Step six: does the path work end to end?

The label path test, which either succeeds and moves the investigation away from MPLS entirely, or fails and reports the hop where it broke. Run it from the ingress router toward the egress loopback, and run it in both directions, because a label path is unidirectional and a fault in one direction is entirely compatible with a working path in the other.

! The six steps, in order, on one router
!
! 1. Enabled on the interface?
P1# show mpls interfaces
!
! 2. Hellos both ways? And what transport address did the peer send?
P1# show mpls ldp discovery detail
!
! 3. Session up? If not, can we reach that transport address?
P1# show mpls ldp neighbor
P1# ping 10.255.0.2 source Loopback0
!
! 4. A binding from the next hop specifically
P1# show ip route 10.255.0.5
P1# show mpls ldp bindings 10.255.0.5 32
!
! 5. A forwarding entry, and is it being used?
P1# show mpls forwarding-table 10.255.0.5 32
!
! 6. The path itself
P1# ping mpls ipv4 10.255.0.5/32

When to use debugging, and when not to

The step-by-step commands answer where the failure is. Debugging answers why, and it is worth turning on only once the location is known, on the one router that matters, filtered to the one neighbour in question. Enabling label distribution debugging across a core during a fault is a reliable way to make the fault worse.

The cases where debugging genuinely helps are narrow: a session that establishes and immediately drops, a label that is advertised and withdrawn repeatedly, or a discovery that appears intermittently. In each of those the state commands show a moving target and the debug shows the sequence.

! Narrow it before enabling it
P1(config)# access-list 50 permit 10.255.0.2
P1# debug mpls ldp session io 50
P1# debug mpls ldp bindings
!
! And a targeted look at one neighbour's full state
P1# show mpls ldp neighbor 10.255.0.2 detail

What to capture before making a change

Four outputs per router, saved as text: the interface state, the discovery detail, the neighbour list, and the forwarding table. These are small, they are stable in a healthy network, and comparing a capture from before a change with one from after it converts an investigation into a difference. In a network where the failures are as quiet as these are, a diff is worth more than any single command.

Symptom Most likely cause First check
Hellos one way only MPLS not enabled on the far side show mpls interfaces there
Hellos both ways, no session Transport address unreachable Ping the advertised address
Session up, no binding for one prefix Summarised, or BGP-learned show ip route for that prefix
Binding present, no forwarding entry Binding is not from the next hop Compare route next hop to binding source
Everything present, large packets fail MTU does not allow for the labels Large ping with do-not-fragment
Intermittent, correlates with link events No synchronisation or session protection show mpls ldp igp sync

Blueprint framing

The CCIE Enterprise Infrastructure v1.1 blueprint places MPLS within its transport technologies and virtualisation domain, and label distribution is examined as mechanism and troubleshooting rather than as a large build. Being able to say what the transport address is, why a session needs a route to reach it, and why a summary removes a label path covers most of what is asked about it.

Start in the middle, not at the bottomThe six steps run downward, but the fastest first move on a live fault is step six — test the label path. It either clears MPLS entirely or names the hop, and then the five steps above it are run on one router rather than on all of them.
Sub claimA fixed order matters more here than in most troubleshooting, because each stage can be healthy while the one below it fails, so an unordered investigation keeps confirming things that were never in doubt.

Conclusion

LDP is a small protocol with an unusual failure profile. It gives every eligible prefix a label and tells the neighbours, and it depends on the interior routing protocol for two things: reachability to the neighbour's transport address, and the set of prefixes that deserve labels. Both dependencies are invisible from the routing protocol's side, which is why a network can be provably healthy by every routing measure while its label paths are broken.

The three tables are where the confusion concentrates. The routing table chooses a next hop with no awareness of labels. The binding table holds a label from every neighbour, most of them unused, and that abundance is what makes reconvergence immediate rather than being a symptom of anything. The forwarding table is the two combined, and a missing entry is always explained by one of the other two rather than by anything within LDP itself.

What breaks it in practice is a short list. A transport address that is not reachable, usually a loopback missing from the interior protocol. A prefix that lost its label to a summary or to being learned by BGP. An interior protocol that put traffic on a link before labels existed there, which synchronisation solves and which nothing detects otherwise. Each of these is found by a specific command, none of them is found by looking at the routing table, and testing the label path directly — rather than pinging the far end and concluding the network is fine — is the habit that separates a ten-minute investigation from a long one. More CCIE Enterprise Infrastructure material — labs, protocol breakdowns and study guides — is collected on the SPOTO CCIE site.

Reference Notes

  1. RFC 5036 specifies LDP, including the discovery mechanism using UDP hello messages on port 646 and session establishment over TCP on the same port number.
  2. RFC 5036 defines the transport address advertised in hello messages as the address used for the TCP session, which may differ from the interface address the hello arrived on.
  3. RFC 5036 describes the role determination in session establishment, in which the router with the higher LDP identifier takes the active role and initiates the TCP connection.
  4. RFC 5036 describes downstream unsolicited advertisement, in which a router distributes label bindings to its peers without those peers requesting them.
  5. RFC 5036 describes liberal label retention, in which a router keeps label bindings received from peers that are not the current next hop for the prefix.
  6. RFC 3031 defines the MPLS architecture, including label switched paths and the separation between label distribution and the routing protocol that determines the path.
  7. RFC 3032 defines the MPLS label stack encoding, giving each label stack entry a size of 4 bytes and reserving label values 0 through 15.
  8. RFC 3032 defines label 3 as implicit null, requesting that the upstream router pop the label before forwarding, and label 0 as explicit null.
  9. RFC 5443 describes LDP IGP synchronisation, in which a link is advertised at maximum cost by the IGP until the LDP session over it has exchanged label bindings.
  10. RFC 8029 specifies the MPLS echo request and reply used to detect data plane failures in a label switched path, which is the mechanism behind MPLS ping and traceroute.
  11. Cisco documentation describes LDP session protection, which maintains a targeted hello relationship alongside a link relationship so the session survives the loss of the directly connected link.
  12. The CCIE Enterprise Infrastructure v1.1 unified exam topics include MPLS within the transport technologies and virtualisation domain.