Glossary / Lightning & layer 2
Dust HTLC
- What is a dust HTLC?
- A dust HTLC is a Lightning payment too small to get its own output in the commitment transaction, so a force close hands it to miners rather than either channel partner.
Lightning channels refuse to create an output for any in-flight payment worth less than the dust limit plus its rescue fee, and that amount becomes miner fee. At a 546 satoshi dust limit and a 5,000 per kiloweight feerate, anything under 3,861 satoshis is trimmed. The money is only lost if the channel force-closes while that payment is still moving.
How it works
A dust HTLC is decided by arithmetic rather than judgement: the dust limit the channel owner chose, plus what claiming the payment on chain would cost.
BOLT 3 calls the discarded output trimmed. For a payment you are offering, the channel checks the amount minus the HTLC-timeout fee; for one you are receiving, the amount minus the HTLC-success fee. Those two transactions weigh 663 and 703 weight units on a channel without anchors, so at a feerate_per_kw of 5,000 they cost 3,315 and 3,515 satoshis. Against a 546 satoshi dust limit, the offered threshold lands at 3,861 satoshis and the received threshold at 4,061.
BOLT 3's worked example shows the loss. Four payments are in flight at that feerate: offered HTLCs of 5,000 and 1,000 satoshis, received HTLCs of 7,000 and 800. The 5,000 and the 7,000 each get an output. The 1,000 and the 800 are trimmed, and the fee on the commitment transaction rises from a base of 5,340 satoshis to 7,140. That extra 1,800 satoshis is exactly the two vanished payments, paid to whoever mines the close.
Each side picks its own dust_limit_satoshis, so the two commitment transactions of one channel can disagree about which payments count as dust. BOLT 2 makes a node fail the channel if its peer proposes a value below 354 satoshis, and lets it refuse one it considers too large, since a peer with a high limit can publish a commitment stuffed with trimmed payments.
Anchor channels changed the arithmetic. Under option_anchors or zero_fee_commitments the second-stage HTLC transactions carry no fee, so they stop feeding the calculation and the threshold collapses to the bare dust limit. BOLT 3 tells nodes to raise dust_limit_satoshis deliberately in that case, since an output that clears the limit but cannot be swept at real feerates only pollutes the UTXO set.
BOLT 2 also bounds the total rather than each payment. Past a node's max_dust_htlc_exposure_msat, itself a matter of policy, the node should fail an incoming HTLC once committed and should not reveal the preimage, turning a possible loss into a clean failure.
Where you see it
Dust HTLCs show up in a wallet's custody model rather than in its interface, and the 41 wallet reviews here split cleanly on it.
Phoenix runs a real self-custodial Lightning node on your handset, so its channels are yours and so is this exposure; ACINQ charges 0.4% plus 4 satoshis to send, and every one of those sends is an HTLC that trimming can reach. BlueWallet's Lightning side is an account on an LNDHub server, so the operator holds the channels: you never carry a trimmed payment, and you carry that operator instead.
Trimming surfaces again at closing time. BOLT 2 allows closing negotiation only once no HTLCs remain in either commitment transaction, dust HTLCs included, so a 300 satoshi payment no on-chain observer can see still holds a cooperative close open.
Dust HTLC vs dust limit
The dust limit is a number a node picks; a dust HTLC is a payment that lost a comparison against that number plus a fee.
The limit is a channel parameter, set in open_channel and accept_channel and carried by no later message. Trimming is an outcome that moves: without anchors the threshold tracks feerate_per_kw, so the same 2,500 satoshi payment is a real output in a quiet mempool and trimmed in a busy one.
The two also apply at different stages. Bitcoin Core's thresholds, 546 satoshis for a legacy output and 330 for pay-to-witness-script-hash, are relay policy about transactions that exist. A trimmed HTLC never reaches that test, because its output is never written.