Pre-Submission Checklist
LND Version
0.21.0-beta
LND Configuration
/data/lnd/lnd.conf - géré par Ansible
[Application Options]
debuglevel=info
maxpendingchannels=5
listen=localhost
rpclisten=0.0.0.0:10009
tlsautorefresh=true
tlsdisableautofill=true
tlsextradomain=localhost
rpcmiddleware.enable=true
bitcoind.rpchost=127.0.0.1:8332
bitcoind.zmqpubrawblock=tcp://127.0.0.1:28332
bitcoind.zmqpubrawtx=tcp://127.0.0.1:28333
bitcoin.basefee=1000
bitcoin.feerate=1000
minchansize=1000000
accept-keysend=true
accept-amp=true
protocol.wumbo-channels=true
coop-close-target-confs=24
protocol.simple-taproot-chans=true
wtclient.active=true
gc-canceled-invoices-on-startup=true
gc-canceled-invoices-on-the-fly=true
ignore-historical-gossip-filters=1
stagger-initial-reconnect=true
payments-expiration-grace-period=600s
[bolt]
db.bolt.auto-compact=true
db.bolt.auto-compact-min-age=168h
[db]
db.backend=postgres
[postgres]
db.postgres.dsn=
db.postgres.timeout=10s
[Bitcoin]
bitcoin.active=true
bitcoin.mainnet=true
bitcoin.node=bitcoind
[tor]
tor.active=true
tor.v3=true
tor.streamisolation=false
tor.skip-proxy-for-clearnet-targets=true
Backend Version
v30.2.0
Backend Configuration
bitcoin.conf - géré par Ansible
server=1
txindex=1
deprecatedrpc=create_bdb
Network
listen=1
listenonion=1
proxy=127.0.0.1:9050
bind=127.0.0.1
Connections
rpcauth=
rpccookieperms=group
rpcbind=0.0.0.0
ZMQ
zmqpubrawblock=tcp://0.0.0.0:28332
zmqpubrawtx=tcp://0.0.0.0:28333
Electrs
whitelist=download@127.0.0.1
Performances
maxconnections=40
maxuploadtarget=5000
dbcache=2000
blocksonly=0
rpcthreads=16
rpcworkqueue=256
OS/Distribution
- database backend: PostgreSQL (via Patroni HA cluster, 3 nodes, synchronous_commit=on * PostgreSQL version: 18.4 (Ubuntu 18.4-1.pgdg24.04+1) * OS: Ubuntu (Proxmox VM)
Bug Details & Steps to Reproduce
We hit the same "invalid revocation" force-close described in #8049, despite running a version
(v0.21.0-beta) well past the retry-logic fixes referenced in that issue (#7927, #7992, milestone v0.18.0).
This may indicate the retry logic doesn't cover this specific query path, or that retries are
exhausted under prolonged lock contention.
Actual behaviour
A PostgreSQL checkpoint began at 21:46:23 CEST and took 115 seconds to complete (finished 21:48:19).
During this window, several concurrent transactions failed with SQLSTATE 40001. One of these, at
21:47:26.832 CEST, was processing an HTLC update and resulted in LND sending an "invalid revocation"
error to the peer, causing a force-close — even though the actual cause was local database
contention, not an invalid revocation from the peer.
LND log:
2026-07-25 21:47:26.832 [ERR] HSWC: ChannelLink(...): failing link: unable to accept revocation:
unable to restore remote unsigned local updates: ERROR: could not serialize access due to
read/write dependencies among transactions (SQLSTATE 40001) with error: invalid revocation
PostgreSQL log (same timestamp):
2026-07-25 21:47:26.832 CEST ERROR: could not serialize access due to read/write dependencies among transactions
DETAIL: Reason code: Canceled on identification as a pivot, during conflict in checking.
STATEMENT: INSERT INTO channeldb_kv (key, value, parent_id) VALUES($1, $2, $3)
ON CONFLICT (key, parent_id) WHERE parent_id IS NOT NULL DO UPDATE SET value=$2
WHERE channeldb_kv.value IS NOT NULL
Confirmed no Patroni leader change occurred during this window (continuous "I am the leader with
the lock" logs before/during/after, via journalctl -u patroni).
Expected Behavior
Per the retry logic introduced in #7927/#7992, SQLSTATE 40001 should be caught and retried
internally rather than surfaced to the peer as a protocol-level "invalid revocation" error
resulting in a force-close.
Debug Information
The remote peer (running CLN) reported receiving 6 similar "invalid revocation" errors from
various peers since the start of the year, suggesting this may not be isolated to our setup.
Environment
No response
Pre-Submission Checklist
LND Version
0.21.0-beta
LND Configuration
/data/lnd/lnd.conf - géré par Ansible
[Application Options]
debuglevel=info
maxpendingchannels=5
listen=localhost
rpclisten=0.0.0.0:10009
tlsautorefresh=true
tlsdisableautofill=true
tlsextradomain=localhost
rpcmiddleware.enable=true
bitcoind.rpchost=127.0.0.1:8332
bitcoind.zmqpubrawblock=tcp://127.0.0.1:28332
bitcoind.zmqpubrawtx=tcp://127.0.0.1:28333
bitcoin.basefee=1000
bitcoin.feerate=1000
minchansize=1000000
accept-keysend=true
accept-amp=true
protocol.wumbo-channels=true
coop-close-target-confs=24
protocol.simple-taproot-chans=true
wtclient.active=true
gc-canceled-invoices-on-startup=true
gc-canceled-invoices-on-the-fly=true
ignore-historical-gossip-filters=1
stagger-initial-reconnect=true
payments-expiration-grace-period=600s
[bolt]
db.bolt.auto-compact=true
db.bolt.auto-compact-min-age=168h
[db]
db.backend=postgres
[postgres]
db.postgres.dsn=
db.postgres.timeout=10s
[Bitcoin]
bitcoin.active=true
bitcoin.mainnet=true
bitcoin.node=bitcoind
[tor]
tor.active=true
tor.v3=true
tor.streamisolation=false
tor.skip-proxy-for-clearnet-targets=true
Backend Version
v30.2.0
Backend Configuration
bitcoin.conf - géré par Ansible
server=1
txindex=1
deprecatedrpc=create_bdb
Network
listen=1
listenonion=1
proxy=127.0.0.1:9050
bind=127.0.0.1
Connections
rpcauth=
rpccookieperms=group
rpcbind=0.0.0.0
ZMQ
zmqpubrawblock=tcp://0.0.0.0:28332
zmqpubrawtx=tcp://0.0.0.0:28333
Electrs
whitelist=download@127.0.0.1
Performances
maxconnections=40
maxuploadtarget=5000
dbcache=2000
blocksonly=0
rpcthreads=16
rpcworkqueue=256
OS/Distribution
Bug Details & Steps to Reproduce
We hit the same "invalid revocation" force-close described in #8049, despite running a version
(v0.21.0-beta) well past the retry-logic fixes referenced in that issue (#7927, #7992, milestone v0.18.0).
This may indicate the retry logic doesn't cover this specific query path, or that retries are
exhausted under prolonged lock contention.
Actual behaviour
A PostgreSQL checkpoint began at 21:46:23 CEST and took 115 seconds to complete (finished 21:48:19).
During this window, several concurrent transactions failed with SQLSTATE 40001. One of these, at
21:47:26.832 CEST, was processing an HTLC update and resulted in LND sending an "invalid revocation"
error to the peer, causing a force-close — even though the actual cause was local database
contention, not an invalid revocation from the peer.
LND log:
2026-07-25 21:47:26.832 [ERR] HSWC: ChannelLink(...): failing link: unable to accept revocation:
unable to restore remote unsigned local updates: ERROR: could not serialize access due to
read/write dependencies among transactions (SQLSTATE 40001) with error: invalid revocation
PostgreSQL log (same timestamp):
2026-07-25 21:47:26.832 CEST ERROR: could not serialize access due to read/write dependencies among transactions
DETAIL: Reason code: Canceled on identification as a pivot, during conflict in checking.
STATEMENT: INSERT INTO channeldb_kv (key, value, parent_id) VALUES($1, $2, $3)
ON CONFLICT (key, parent_id) WHERE parent_id IS NOT NULL DO UPDATE SET value=$2
WHERE channeldb_kv.value IS NOT NULL
Confirmed no Patroni leader change occurred during this window (continuous "I am the leader with
the lock" logs before/during/after, via
journalctl -u patroni).Expected Behavior
Per the retry logic introduced in #7927/#7992, SQLSTATE 40001 should be caught and retried
internally rather than surfaced to the peer as a protocol-level "invalid revocation" error
resulting in a force-close.
Debug Information
The remote peer (running CLN) reported receiving 6 similar "invalid revocation" errors from
various peers since the start of the year, suggesting this may not be isolated to our setup.
Environment
No response