Title
close RPC deadlocked: recorded Taproot shutdown script conflicts with peer lacking option_shutdown_anysegwit, no way to override
Summary
A channel stuck in CHANNELD_SHUTTING_DOWN cannot be closed — neither cooperatively
nor via the unilateraltimeout fallback — because the channel's already-committed
local shutdown script (close_to_addr) is a Taproot (v1 segwit, bc1p...) address,
and the peer does not support option_shutdown_anysegwit. Attempting to override the
destination on a subsequent close call is rejected because it doesn't match the
previously-sent shutdown script. This produces two mutually exclusive error paths with
no RPC-level way to reconcile them, leaving the channel permanently un-closeable
through normal means.
Environment
lightningd version: v26.06.6
- OS:
Ubuntu 24.04.4 LTS
- Channel type:
static_remotekey/even, anchors/even
Steps to reproduce
- Have an open channel (
CHANNELD_NORMAL) with a peer that does not advertise
option_shutdown_anysegwit in its node features.
- Node's default
close_to resolves to a Taproot (bc1p...) address (e.g. via
wallet default address type), and a close is issued, sending a shutdown
message and transitioning the channel to CHANNELD_SHUTTING_DOWN.
- Peer never completes the cooperative close (goes offline / unresponsive). Channel
remains in CHANNELD_SHUTTING_DOWN indefinitely.
- Attempt to force a unilateral close:
lightning-cli close <peer_id> 1
Result:
{
"code": -32602,
"message": "Peer does not allow v1+ shutdown addresses"
}
- Attempt to override the destination with a native SegWit (
bc1q...) address to
work around the above:
lightning-cli newaddr bech32
lightning-cli close <peer_id> 1 <bc1q_address>
Result:
{
"code": -32602,
"message": "Destination address <bc1q_address> does not match already-sent shutdown script <bc1p_address>"
}
Expected behavior
Either:
- The
unilateraltimeout fallback should be able to force a unilateral close
(broadcasting the latest commitment transaction) without depending on constructing
a valid cooperative shutdown script at all, since a unilateral close does not use
close_to for the immediate output — it settles to the standard to-local delayed
script and is later swept by onchaind. The v1+/anysegwit check should not block
this fallback path.
- Or, at minimum, there should be an RPC-level way to reset/override the recorded
shutdown script for a channel that has not yet completed cooperative close, so a
compatible (v0) destination can be substituted and negotiation can proceed.
Actual behavior
The channel is left in a permanent deadlock:
- The
close RPC requires the destination to match the already-sent (Taproot)
shutdown script.
- The already-sent shutdown script is rejected by the peer's feature set.
- No parameter combination of
close resolves this. There does not appear to be a
non-destructive way to reset the local shutdown script or force a unilateral close
that bypasses cooperative-script validation.
Impact
Funds remain safely locked in the channel's on-chain funding output (not lost), but
are inaccessible via any documented RPC path. The only known escapes
(dev-forget-channel, manual hsmtool-based commitment reconstruction) are
destructive/advanced and not appropriate as a routine remedy for what looks like a
straightforward feature-negotiation edge case.
Relevant output (redacted)
listpeerchannels:
{
"peer_id": "<PEER_NODE_ID>",
"peer_connected": false,
"channel_type": {
"bits": [12, 22],
"names": ["static_remotekey/even", "anchors/even"]
},
"state": "CHANNELD_SHUTTING_DOWN",
"scratch_txid": "<SCRATCH_TXID>",
"channel_id": "<CHANNEL_ID>",
"funding_txid": "<FUNDING_TXID>",
"funding_outnum": 1,
"close_to_addr": "<TAPROOT_ADDR bc1p...>",
"close_to": "<close_to scriptPubKey, 5120... / OP_1 witness program>",
"opener": "remote",
"closer": "local",
"to_us_msat": 9889360982,
"total_msat": 10000000000,
"our_to_self_delay": 1201,
"their_to_self_delay": 144,
"state_changes": [
{
"timestamp": "2026-01-14T21:16:29.308Z",
"old_state": "CHANNELD_AWAITING_LOCKIN",
"new_state": "CHANNELD_NORMAL",
"cause": "remote",
"message": "Lockin complete"
},
{
"timestamp": "2026-07-23T13:47:56.871Z",
"old_state": "CHANNELD_NORMAL",
"new_state": "CHANNELD_SHUTTING_DOWN",
"cause": "user",
"message": "User or plugin invoked close command"
}
],
"status": ["Loaded from database"],
"htlcs": []
}
Peer's advertised features (from listnodes) do not include
option_shutdown_anysegwit (bit 26/27) — happy to paste the raw feature bitfield if
useful, omitted here as it may help fingerprint the peer.
Additional notes
- The peer has been offline (
peer_connected: false) for the entire duration, so
cooperative resolution isn't possible regardless — the request here is specifically
about the unilateral fallback path being blocked by the same script-compatibility
check that only matters for the cooperative path.
- Happy to provide additional redacted output or test against a patch if useful.
- Full Disclosure - used AI to assist in generating content.
Title
closeRPC deadlocked: recorded Taproot shutdown script conflicts with peer lackingoption_shutdown_anysegwit, no way to overrideSummary
A channel stuck in
CHANNELD_SHUTTING_DOWNcannot be closed — neither cooperativelynor via the
unilateraltimeoutfallback — because the channel's already-committedlocal shutdown script (
close_to_addr) is a Taproot (v1 segwit,bc1p...) address,and the peer does not support
option_shutdown_anysegwit. Attempting to override thedestination on a subsequent
closecall is rejected because it doesn't match thepreviously-sent shutdown script. This produces two mutually exclusive error paths with
no RPC-level way to reconcile them, leaving the channel permanently un-closeable
through normal means.
Environment
lightningdversion:v26.06.6Ubuntu 24.04.4 LTSstatic_remotekey/even,anchors/evenSteps to reproduce
CHANNELD_NORMAL) with a peer that does not advertiseoption_shutdown_anysegwitin its node features.close_toresolves to a Taproot (bc1p...) address (e.g. viawallet default address type), and a
closeis issued, sending ashutdownmessage and transitioning the channel to
CHANNELD_SHUTTING_DOWN.remains in
CHANNELD_SHUTTING_DOWNindefinitely.bc1q...) address towork around the above:
Expected behavior
Either:
unilateraltimeoutfallback should be able to force a unilateral close(broadcasting the latest commitment transaction) without depending on constructing
a valid cooperative shutdown script at all, since a unilateral close does not use
close_tofor the immediate output — it settles to the standard to-local delayedscript and is later swept by
onchaind. The v1+/anysegwit check should not blockthis fallback path.
shutdown script for a channel that has not yet completed cooperative close, so a
compatible (v0) destination can be substituted and negotiation can proceed.
Actual behavior
The channel is left in a permanent deadlock:
closeRPC requires the destination to match the already-sent (Taproot)shutdown script.
closeresolves this. There does not appear to be anon-destructive way to reset the local shutdown script or force a unilateral close
that bypasses cooperative-script validation.
Impact
Funds remain safely locked in the channel's on-chain funding output (not lost), but
are inaccessible via any documented RPC path. The only known escapes
(
dev-forget-channel, manualhsmtool-based commitment reconstruction) aredestructive/advanced and not appropriate as a routine remedy for what looks like a
straightforward feature-negotiation edge case.
Relevant output (redacted)
Peer's advertised features (from
listnodes) do not includeoption_shutdown_anysegwit(bit 26/27) — happy to paste the raw feature bitfield ifuseful, omitted here as it may help fingerprint the peer.
Additional notes
peer_connected: false) for the entire duration, socooperative resolution isn't possible regardless — the request here is specifically
about the unilateral fallback path being blocked by the same script-compatibility
check that only matters for the cooperative path.