Lightning Network & Layer 2

Lightning Troubleshooting: Failed Transactions

A ceramic bead beside a slack section of thread between stone blocks, an editorial metaphor for a failed payment route.

A Lightning payment can fail before it leaves your node or at a node along the route, or it can get stuck on the way. A channel can also end in a force close that locks your funds for a while. This guide explains what each common error means, how to check it with diagnostic commands and how to fix it, from liquidity problems to node connectivity and recovery.

The commands are for LND (lncli). Core Lightning (CLN) and Eclair word their errors differently, but the causes are the same, and so are the ideas behind the fixes.

Common Payment Failures and Error Codes

Lightning payment failures return specific error codes. In LND, a failed payment ends with one failure reason, such as NO_ROUTE, INSUFFICIENT_BALANCE or TIMEOUT. Along the way, nodes on the route can send back forwarding errors for single attempts; your node learns from them and tries again. Here are the most frequent ones and what they actually mean.

How LND tries to pay an invoice. Step 1: it checks that all your channels together can send the amount; if not, the payment fails with INSUFFICIENT_BALANCE. Step 2: it picks a route from its map of the network; if no route is left that can carry the payment, even split into parts, it fails with NO_ROUTE. Step 3: it sends the payment as an HTLC passed node to node. When the recipient settles it, you are paid and get proof of payment. If a node on the route sends an error back (TEMPORARY_CHANNEL_FAILURE, FEE_INSUFFICIENT, INCORRECT_CLTV_EXPIRY or CHANNEL_DISABLED), your node updates its map and goes back to step 2 to pick another route. It keeps trying for up to 60 seconds, LND's default; after that it starts no new attempts, and once every attempt already sent has failed, the payment fails with TIMEOUT. An attempt still on its way keeps the payment IN_FLIGHT, and can still succeed.
A payment usually fails for good in one of three ways: not enough balance, no route left, or no time left. The errors that nodes on the route send back are part of the search: your node learns from each one and tries another route.

FAILURE_REASON_NO_ROUTE

Your node can’t find a path through the network that can carry the payment to the destination: either there was none from the start, so the payment never left your node, or it tried every path it found and each one failed.

Common causes:

  • No channels have sufficient outbound liquidity for the payment amount
  • The destination node is offline or has no public channels
  • Intermediate routing nodes along all possible paths are offline
  • Your node’s channel graph is outdated or incomplete
  • The payment amount exceeds the maximum HTLC size on available routes

Diagnosis:

First, check your outbound liquidity across all channels:

lncli listchannels | jq '[.channels[] | select(.active==true)] | map({alias: .peer_alias, local: .local_balance, remote: .remote_balance, capacity: .capacity}) | sort_by(-.local | tonumber)'

This shows your active channels sorted by available outbound (local) balance. If no single channel has enough outbound liquidity, the payment cannot go out in one piece — though multi-path payments (MPP) can split it across channels.

Check if the destination is reachable at all:

lncli getnodeinfo --pub_key=DESTINATION_PUBKEY

If this returns an error, the destination node either doesn’t exist in your graph or has no public channels. Verify your graph is current:

lncli getnetworkinfo

Compare num_nodes and num_channels against known network stats. If your numbers are significantly lower, your graph needs updating. Restarting your node or waiting for gossip propagation usually resolves this.

Solutions:

  • Open a direct channel to the destination or to a well-connected node near them
  • Use Lightning Loop to rebalance existing channels and move liquidity outbound
  • Let the payment split into parts: lncli payinvoice already does, into up to 16 parts by default (--max_parts); in other wallets, check that multi-path payments are on
  • Reduce payment amount and send in smaller chunks if MPP isn’t available
  • Wait and retry — temporary routing node outages resolve themselves

FAILURE_REASON_INSUFFICIENT_BALANCE

All your channels together don’t hold enough that you can spend to cover the amount. LND checks this before it looks for a route, so the payment never leaves your node. If the total is enough but no single channel is, LND tries to split the payment instead, and if no split works either, the payment fails as NO_ROUTE.

Common causes:

  • Channel reserve requirements consume part of your balance (typically 1% of channel capacity)
  • In-flight HTLCs (payments still on their way) tie up liquidity until they settle or fail
  • Routing fees come on top of the amount: if your balance covers the amount but not the fees, the payment fails as NO_ROUTE instead
  • Pending channel updates haven’t been reflected in your balance yet

Diagnosis:

Check pending HTLCs that may be locking up funds:

lncli listchannels | jq '.channels[] | select(.pending_htlcs | length > 0) | {chan_id: .chan_id, alias: .peer_alias, pending_htlcs: .pending_htlcs}'

Review your actual spendable balance vs. displayed balance:

lncli walletbalance
lncli channelbalance

In channelbalance, local_balance is what sits on your side right now. A payment you are still sending has already left it and shows in unsettled_remote_balance until it settles or fails; incoming payments still on their way show in unsettled_local_balance. Channel reserves further reduce this. For a 1M sat channel, expect roughly 10,000 sats locked as reserve that you can never spend through that channel.

An example 1,000,000-sat channel drawn as a bar. Your side holds 400,000 sats (local_balance) and your peer's side 550,000 (remote_balance). Between them, 50,000 sats are in flight: a payment that has already left your side and comes back to you if it fails (unsettled_remote_balance). At the far end of your side, a thin slice of 10,000 sats is the reserve, 1% of the channel, which you must keep (chan_reserve_sat). You can send now: 400,000 minus the 10,000 reserve, minus routing fees, so a little under 390,000. Your peer's side is roughly what you can receive.
What you can send is a little less than your side of the channel. The 1% reserve always stays, and routing fees come on top of the amount. A payment still in flight has already left your side. If you opened the channel, a little more is kept back for on-chain fees.

Solutions:

  • Wait for pending HTLCs to settle or fail; one that fails returns its funds to your side
  • Account for reserves and fees when calculating available balance — your real spendable amount is always less than your channel balance shows
  • Open larger channels to minimize the relative impact of reserve requirements
  • Use proper channel management to keep balanced liquidity

FAILURE_REASON_TIMEOUT

Your node kept trying routes until the payment timeout ran out (60 seconds by default in LND), then stopped starting new attempts. Attempts already on their way are not cancelled: LND waits until each one settles or fails, so the payment can show as IN_FLIGHT for a while. Once it shows FAILED, nothing is locked and you can retry. If a late attempt gets through instead, it shows SUCCEEDED: you have paid, so don’t pay again. If it stays in flight for a long time, an attempt is stuck at a node along the route, and the steps below apply.

When the payment timeout runs out, 60 seconds by default in LND, your node starts no new attempts, but attempts already sent go on: LND waits until each one settles or fails. If all of them failed and came back with an error, the payment's status is FAILED with reason TIMEOUT, nothing is locked any more, and you can retry; your node usually avoids the slow node. If one hasn't come back because a node on the route stopped answering, the status stays IN_FLIGHT and your funds stay locked, block after block, until it settles, fails or reaches its deadline: up to 2,016 blocks, about two weeks, in LND. Wait: don't pay again and keep your node online. If a late attempt gets through instead, the status is SUCCEEDED: you have paid.
A timeout and a stuck payment look alike; the payment’s status tells them apart. FAILED with reason TIMEOUT means nothing is locked, so retry. IN_FLIGHT means an attempt is still out there: paying again won’t free it, so leave your node online and let it end. If a late attempt gets through, the status turns SUCCEEDED and you have paid.

Common causes:

  • An intermediate node went offline while forwarding the payment
  • The destination node received the HTLC but hasn’t settled it
  • Network congestion is causing delayed forwarding along the route
  • A node in the path has a slow or overloaded implementation

Diagnosis:

Check for in-flight payments:

lncli listpayments --include_incomplete | jq '.payments[] | select(.status=="IN_FLIGHT") | {hash: .payment_hash, amount: .value_sat, creation_date: .creation_date}'

Examine the specific payment’s HTLC status:

lncli trackpayment PAYMENT_HASH

This gives real-time updates on the payment’s progress through the network. If the HTLC is stuck at a specific hop, you’ll see which node is holding it.

Solutions:

  • If an attempt is stuck, wait: your funds come back when it fails or when its HTLC deadline passes. LND accepts forwards locked for up to 2,016 blocks (about two weeks), and an HTLC that still can’t be settled cleanly at its deadline forces the channel holding it to close on-chain
  • Do NOT send a duplicate payment while one is in-flight (risk of paying twice)
  • If consistently happening with a specific peer, consider closing that channel
  • If plain timeouts keep happening, give payments more time with lncli payinvoice --timeout (60 seconds by default)
  • If the stuck payment ends as FAILED, retry: LND remembers the failure and usually routes around that node. If it ends as SUCCEEDED, you have paid, so don’t pay again

Forwarding Errors From Nodes on the Route

When a node on the route can’t forward an attempt, it sends an error back. LND records it on that attempt (in the payment’s htlcs list) and keeps going; FAILURE_REASON_ERROR, a final failure reason, is for rarer errors it can’t recover from. The most common forwarding errors:

  • FEE_INSUFFICIENT: Your node calculated a route using outdated fee data. The routing node’s fees have increased since your last graph update.
  • CHANNEL_DISABLED: A channel along the route has been disabled by one of its peers, often temporarily during maintenance.
  • TEMPORARY_CHANNEL_FAILURE: The forwarding node can’t process the HTLC right now. Usually a transient liquidity or capacity issue on their end.
  • INCORRECT_CLTV_EXPIRY: The CLTV (CheckLockTimeVerify) delta doesn’t match what the routing node requires. Your graph data for that node’s policy is stale.

Most of these resolve on retry because your node updates its graph with the error information and picks a different route. If a specific error persists, run lncli queryroutes --dest=PUBKEY --amt=AMOUNT to see what routes your node is attempting to use.

Channel Issues: Force Closures and Stuck Channels

Channel problems cause the most stress for node operators because they involve on-chain transactions, waiting periods, and locked funds. Understanding force closures is essential for anyone running a Lightning node.

Force-Closed Channels

A force closure happens when one peer unilaterally broadcasts the latest channel state to the blockchain. This bypasses the cooperative close process and triggers a timelock on your funds.

Why channels get force-closed:

  • Your peer’s node went offline for an extended period and your node gave up waiting
  • Your own node experienced downtime and your peer force-closed to recover their funds
  • A pending HTLC is about to expire on-chain, forcing a closure to claim it
  • Channel state became inconsistent between peers (rare but serious)
  • You or your peer deliberately force-closed due to unresolvable routing issues

Checking pending force closures:

lncli pendingchannels | jq '.pending_force_closing_channels[] | {channel_point: .channel.channel_point, limbo_balance: .limbo_balance, blocks_til_maturity: .blocks_til_maturity, recovered_balance: .recovered_balance}'

The blocks_til_maturity field tells you how many more blocks until your funds are spendable. If you started the force close, you wait the delay your peer set when the channel opened: with LND’s defaults, 144 blocks (about a day) on channels under about 1.2 million sats, rising to 2,016 blocks (about two weeks) on the largest. lncli listchannels shows yours as csv_delay under local_constraints. If your peer force-closed on you, your side is spendable one block after the close confirms on today’s anchor channels, but any pending HTLCs add complexity.

When your side of a closed channel can be spent again. Cooperative close, where both sides sign one transaction: spendable as soon as it confirms. Your peer force-closes by publishing the latest balance: your side is spendable one block after the close confirms. You force-close: your side shows as limbo_balance and stays locked for the delay your peer set when the channel opened. With LND's defaults that is 144 blocks, about a day, on channels under about 1.2 million sats, and up to 2,016 blocks, about two weeks, on the largest. Then your node sweeps it into your wallet; lncli pendingchannels shows blocks_til_maturity counting down.
Closing the channel yourself without your peer costs you the longest wait. A cooperative close pays both sides at once. If your peer force-closes, your side is free one block later; if you do, it waits out the delay your peer chose. Payments in flight at the close are settled on-chain separately.

Waiting-close channels:

lncli pendingchannels | jq '.waiting_close_channels'

These are channels where a closing transaction has been broadcast but not yet confirmed. During high-fee periods, this state can persist for hours or days. If that transaction is an old state your peer should no longer publish, your node, or your watchtower while your node is offline, answers with a penalty transaction that takes the whole channel.

Zombie Channels

Zombie channels are channels whose peer has stopped answering for a long time. They show as inactive in your channel list, can’t route payments and keep your funds tied up.

lncli listchannels | jq '[.channels[] | select(.active==false and .private==false)] | length'

If you have many inactive public channels, consider closing them to free up on-chain funds for productive channels. Before closing, attempt to reconnect:

lncli connect PEER_PUBKEY@ADDRESS:PORT

If the peer comes back, a cooperative close via lncli closechannel --chan_point=FUNDING_TXID:OUTPUT_INDEX is the cleanest resolution. If it consistently can’t be reached, a cooperative close isn’t possible, because both peers have to sign it, and LND refuses it while the peer is offline. Add --force to close the channel on your own, and expect your side to stay locked for the delay described above.

Liquidity Problems

Liquidity management is the operational core of running a Lightning node. Most payment failures trace back to liquidity imbalances. For a comprehensive treatment of this topic, see our Lightning routing optimization guide.

Two channels with opposite problems. In the first, your side is almost empty, so you can't send. The fixes move the divider toward the middle by refilling your side: Loop In, which swaps on-chain bitcoin in; a circular rebalance that pulls sats in from a channel that is too full; or receiving payments through it. Or you open a new channel, which starts with everything on your side. In the second, your side is almost full, so you can't receive. The fixes empty your side: Loop Out, which swaps sats out to on-chain bitcoin; a circular rebalance that pushes sats out to a channel that is too empty; or spending through it. Or you get a channel opened to you, for example through LN+ or Magma. Routing nodes aim to keep their channels between 25 and 75% on their own side.
First find out which side is empty, then pick a fix that moves the balance the other way. Loop In and Loop Out do opposite things, and a channel you open yourself gives you room to send, not to receive. Set alerts for when a channel drops below 10% or rises above 90% on your side.

Depleted Outbound Liquidity

After sending many payments, your channels fill up on the remote side. You have inbound capacity but can’t send. This manifests as NO_ROUTE or INSUFFICIENT_BALANCE for outgoing payments.

Diagnosis:

lncli listchannels | jq '.channels[] | select(.active==true) | {alias: .peer_alias, local_pct: ((.local_balance|tonumber) / ((.local_balance|tonumber) + (.remote_balance|tonumber)) * 100 | floor)} | select(.local_pct < 20)'

This shows active channels where your local (outbound) balance is below 20% of capacity. These channels need rebalancing.

Rebalancing options:

  • Circular rebalance: Send a payment to yourself through the network: out through a channel where your side is full, back in through the depleted one. Tools like bos rebalance (Balance of Satoshis) automate this.
  • Loop In: Use Lightning Loop to swap on-chain bitcoin for Lightning sats that arrive on your side of a channel, adding outbound capacity.
  • Receive over Lightning: The simplest rebalance — every payment you receive moves sats back to your side.

Depleted Inbound Liquidity

The opposite problem: you’ve received many payments, your channels are full on your side, and you can’t receive more. Merchants and service providers hit this frequently.

Solutions:

  • Loop Out: Swap Lightning sats for on-chain bitcoin via submarine swap: your side of the channel empties, which is room to receive
  • Request inbound channels: Services like LN+ and Magma offer inbound liquidity
  • Open new channels, then spend through them: a channel you open starts with everything on your side, so it gives you room to receive only after you pay some of it away
  • Drain channels: Spend or rebalance to push local balance out

Unbalanced Channels Causing Routing Failures

If you route payments for others, channel balance directly affects your routing revenue. A channel depleted in one direction can’t forward payments that direction. Monitor your routing success rate:

lncli fwdinghistory --start_time=-30d | jq '.forwarding_events | length'

Compare this against failed forward attempts in your logs to calculate your routing success rate. A healthy routing node maintains most channels between 25-75% local balance. For more on optimizing fees and liquidity, check our Lightning fees guide.

Node Connectivity Issues

Connectivity problems prevent your node from communicating with peers, propagating gossip, and forwarding payments. They’re often the hidden cause behind what looks like a routing or liquidity problem.

Tor Connectivity

Many home Lightning nodes run behind Tor for privacy. Tor adds latency and occasional reliability issues.

Common Tor problems:

  • Tor circuit establishment fails, preventing peer connections
  • Onion service descriptor publication fails, making your node unreachable
  • High latency causes HTLC forwarding timeouts

Check Tor status:

systemctl status tor
# Confirm that traffic through Tor works (the reply shows "IsTor": true)
torsocks curl -s https://check.torproject.org/api/ip

If Tor is down, restart it: sudo systemctl restart tor. If problems persist, stop Tor, delete only its cached network files (the cached-* files in its data directory, usually /var/lib/tor) and start it again so it downloads them afresh. Don’t wipe the whole directory: an onion service set up with HiddenServiceDir often keeps its private key there, and deleting it changes that service’s .onion address for good. By default, LND keeps its own onion key in its own directory (v3_onion_private_key).

Hybrid mode: Consider running your node in hybrid mode (both Tor and clearnet) if privacy requirements allow it. This dramatically improves connectivity and payment reliability while still offering a Tor endpoint for privacy-focused peers.

Peer Disconnections

Frequent disconnections from specific peers cause payment failures and can trigger force closures if prolonged.

lncli listpeers | jq '.peers[] | {pubkey: .pub_key, bytes_recv: .bytes_recv, ping_time: .ping_time, sat_sent: .sat_sent}'

High ping times (above 5 seconds) indicate connectivity problems. If a peer consistently shows high latency or drops offline, the channel may not be worth maintaining.

Database and Disk Issues

LND’s channel database (channel.db) can grow large and cause performance problems. A corrupted database is one of the worst scenarios for a Lightning node operator.

# Check database size
ls -lh ~/.lnd/data/graph/mainnet/channel.db

# Check disk space
df -h /

If channel.db exceeds 1GB, consider compacting it during scheduled downtime. Always maintain current SCB (Static Channel Backup) files — these are your recovery lifeline if the database corrupts:

lncli exportchanbackup --all --output_file=/path/to/backup/channel-backup-$(date +%Y%m%d).backup

Prevention Tips

Most Lightning failures are preventable with good operational practices. These habits separate reliable nodes from problematic ones.

Monitoring and Alerts

  • Balance monitoring: Set up alerts when any channel drops below 10% or above 90% local balance. Tools like ThunderHub, RTL (Ride The Lightning), and LNDmon provide dashboards and notification options.
  • Uptime monitoring: Use a simple cron job or external service to ping your node. If uptime drops below 99%, investigate connectivity issues before they cause force closures.
  • Disk space alerts: Run out of disk space and your node crashes ungracefully, risking database corruption. Monitor disk usage and set alerts at 80% capacity.
  • Backup automation: Script a copy of LND’s channel.backup to an off-node location each time it changes, after every channel open or close; a daily copy can miss a channel opened since. If your node hardware fails, your seed and that file recover the settled balance of each channel it lists, once its peer comes online and closes it.

Channel Selection

  • Connect to well-maintained, high-uptime nodes — check their track record on amboss.space or 1ML before opening channels
  • Avoid opening channels smaller than 500,000 sats — small channels have proportionally high reserve requirements and limited routing utility
  • Diversify your peer set across different node implementations, geographic regions, and network positions
  • Open channels during low-fee periods to minimize the on-chain cost of channel creation

Regular Maintenance

  • Update your node software promptly — LND, CLN, and Eclair releases often fix routing bugs and improve payment reliability
  • Review and close zombie channels monthly to free up capital
  • Rebalance proactively rather than waiting for payments to fail
  • Test your backup restoration process at least once — an untested backup is not a backup

Fee Policy

Incorrect fee settings cause indirect failures. Fees too high mean nobody routes through you (reducing your graph presence). Fees too low attract liquidity draining. Start with moderate fees and adjust based on actual routing volume. Our fee guide covers the economics in detail.

Emergency Recovery Procedures

When things go seriously wrong, knowing the recovery steps prevents panic-driven mistakes.

Node Won’t Start

  1. Check logs first: journalctl -u lnd --since "1 hour ago" -n 200
  2. If the log says Waiting for wallet encryption password, run lncli unlock and enter your wallet password: LND needs it after every restart. A locked wallet is not a corrupted one.
  3. If the database is corrupted, do NOT delete it. Copy it to a safe location, then attempt repair.
  4. If repair fails, restore your newest SCB backup on a node using the same seed. The peers listed in it then force-close those channels, and your settled balance comes back on-chain once each peer is online. Channels opened after that backup are not covered.

Stuck Pending Channel Open

A channel funding transaction was broadcast but hasn’t confirmed, and the channel is stuck in a pending state.

lncli pendingchannels | jq '.pending_open_channels'

If the funding transaction has too low a fee, you can use CPFP (Child Pays For Parent) to bump it if your LND version supports it. Otherwise, wait for the transaction to either confirm or fall out of the mempool.

Recovering After Extended Downtime

If your node was offline for days, channels may have been force-closed by peers. After restarting:

  1. Let the node fully sync the blockchain and channel graph
  2. Check lncli pendingchannels for any force-closed channels
  3. Verify your on-chain balance includes recovered funds: lncli walletbalance
  4. Reconnect to remaining peers and assess which channels survived
  5. Consider opening new channels to replace lost ones, following the fundamentals of Lightning channel selection
Part of our free Bitcoin course: This topic is covered in depth in Lightning Payments in Practice: Sending, Receiving and Troubleshooting from the Lightning Network & Bitcoin Nodes course.

Frequently Asked Questions

My payment failed with NO_ROUTE but the destination exists. What gives?

Your node can see the destination in its graph but cannot construct a viable path with sufficient liquidity. This usually means your outbound capacity is too low or too fragmented. Try: (1) rebalancing your largest channel to increase outbound, (2) splitting the payment with MPP if your wallet supports it, or (3) opening a channel to a node that’s well-connected to the destination’s neighborhood.

A force-close happened and my funds show “limbo_balance.” Are they lost?

No. Limbo balance means the funds are locked in a time-locked on-chain transaction. They’ll become spendable after the timelock expires. If you initiated the force close, that is the delay your peer set when the channel opened: with LND’s defaults, 144 blocks (about a day) on channels under about 1.2 million sats and up to 2,016 blocks (about two weeks) on the largest. If your peer did, your side is spendable one block after the close confirms. Check lncli pendingchannels for the blocks_til_maturity countdown. The funds are safe, just temporarily inaccessible.

How do I prevent force closures?

Maintain high uptime (99%+), keep your node software updated, ensure stable internet connectivity, and monitor disk space. Most force closures happen because a node went offline for too long. Running a watchtower protects against your peer broadcasting old channel states during your downtime, but it doesn’t prevent the force closure itself.

Should I use keysend or regular invoices for payments?

Regular invoices are more reliable because the destination explicitly creates the payment parameters. Keysend (spontaneous payments) can fail if the destination doesn’t support it or if probe-based routing decisions are needed. For routine payments, always prefer invoices. Keysend is useful for tips and donations where requesting an invoice isn’t practical.

My channel database is huge. Can I safely compact it?

Yes, with LND’s own setting. Export an SCB backup and check that the disk has free space, then set db.bolt.auto-compact=true in lnd.conf and restart LND: it compacts its database files on startup. It writes the compacted database to a temporary file and swaps it in only when that is complete, so a failed compaction leaves the original in place. The setting is off by default because compaction needs extra disk space while it runs. Never compact the database with a separate tool while LND is running.

What’s the difference between a cooperative close and a force close?

A cooperative close requires both peers to be online and agree on the final balance split. It produces a single on-chain transaction with no timelocks — funds are immediately spendable after confirmation. A force close is unilateral: one peer broadcasts the commitment transaction, triggering timelocks and potentially higher on-chain fees. Always prefer cooperative closes when possible.

Payments keep failing through one specific channel. Should I close it?

First, check if the issue is liquidity (rebalanceable) or the peer’s reliability (systemic). Run lncli listchannels | jq '.channels[] | select(.chan_id=="CHANNEL_ID")' to check the channel’s status, uptime, and pending HTLCs. If the peer is consistently offline or unresponsive, closing the channel and reopening with a more reliable peer is the better long-term decision. If it’s just a balance issue, rebalance instead.

Filed under: Lightning Network & Layer 2
← Back to All Articles