LND v0.20.1-beta Released: Point Release Fixes
Lightning Labs released LND v0.20.1-beta on February 12, 2026. This is a maintenance release you actually want to install.
It fixes 15 bugs discovered since v0.20.0-beta dropped in November, including several that could prevent your node from starting, crash your payments, or lock up during shutdown. If you’re running v0.20.0-beta, upgrade. If you’re still on v0.19.x and held off because of upgrade issues, you can now jump straight to v0.20.1-beta safely.
No database migrations. No breaking changes. Just fixes.
The big one: backwards compatibility
The most user-facing bug in v0.20.0-beta was issue #10528: nodes upgrading directly from v0.19.x to v0.20.x would fail to start with a cryptic error: “unable to decode features: EOF”
Here’s what happened. In v0.20.0-beta, the developers changed how channel edge features get serialized. The old format stored raw feature bytes. The new format uses length-prefixed encoding. The deserialization code expected the new format, but databases migrated from v0.19.x still had the legacy format. Boom: startup failure.
The fix in PR #10529 is clever. The code now auto-detects which format it’s reading. Because the legacy format always has at least one bit set in the first byte, the first two bytes can never encode a value equal to len-2 in the new format. That’s the detection signal. Simple, elegant, and it works.
If you tried to upgrade from v0.19.x to v0.20.0-beta and hit this wall, v0.20.1-beta fixes it. You can upgrade now.
The gossiper deadlock
This one came from fuzz testing by Matt Morehouse. Under certain conditions, processing a malformed channel_announcement message could deadlock the gossiper during shutdown. Your node wouldn’t shut down cleanly. You’d have to forcefully kill it.
The root cause: an error handling channel buffered for one message, but some code paths could send two. The receiving side doesn’t read from this channel, so the sending goroutine would block forever on the second send.
The fix in PR #10540 bumps the buffer from 1 to 2 messages. That’s the immediate solution. A more thorough refactor using the actor model is planned for later.
This is why fuzz testing matters. Nobody discovered this in the wild because the conditions are rare. But “rare” isn’t “impossible,” and a deadlock is a deadlock. Better to catch it in testing than in production.
Startup failures and race conditions
Three separate issues could prevent LND from starting:
Source node race condition: Two goroutines trying to update the node’s own announcement at the same time could create a race. PR #10371 fixed the synchronization, and PR #10449 improved timestamp comparison to use full precision instead of seconds-only.
TLS certificate regeneration bug: If either the TLS certificate or key file existed (but not both), the TLS manager would fail to start instead of regenerating both files. You’d have to manually delete the orphaned file to recover. PR #10399 fixed that.
Mission control deserialization failures: A corrupted or incompatible payment result in the mission control store would block startup. PR #10383 added error recovery that skips malformed entries and deletes them, so startup can proceed.
All three of these are “why won’t my node start?” bugs. Frustrating for operators, and now fixed.
Routing and gossip improvements
Several race conditions in the channel graph database got cleaned up. PR #10433 fixed public key caching races in Node.PubKey() and ChannelEdgeInfo.NodeKey1/NodeKey2(), plus added proper mutex protection to cache access in DisconnectBlockAtHeight.
Channels with both policies disabled at startup could never be used for routing, even after policies were re-enabled. PR #10378 fixed the startup logic so policy state changes are properly tracked.
Duplicate addresses were being added to node announcements and getinfo output. PR #10341 added deduplication.
Better fee estimates for LSP wallets
The EstimateRouteFee RPC got smarter about detecting Lightning Service Provider (LSP) setups. PR #10396 implements a heuristic that probes up to 3 unique LSPs when route hints indicate an LSP configuration, then returns the worst-case (most expensive) fee estimate.
This is conservative, but conservative is good when you’re budgeting for a payment. You don’t want to undershoot the fee and have your payment fail.
Related: EstimateRouteFee probes were failing against Eclair and LDK nodes because they didn’t include payment addresses/secrets. PR #10439 fixed that, ensuring compatibility with nodes that enforce these fields.
Performance tweaks
If you’re running LND with the native SQL backend (Postgres or SQLite), there are two new config options in v0.20.1-beta:
db.postgres.channeldb-with-global-lock(defaults tofalse, enabling concurrent access)db.postgres.walletdb-with-global-lock(defaults totrue, single-writer mode for safety)
The channel database is now fully concurrent-safe and can benefit from parallel access. The wallet subsystem isn’t quite there yet, so it defaults to single-writer mode. PR #10394 added these controls.
PR #10356 optimized the IsPublicV1Node query to use UNION ALL instead of OR conditions, improving performance when checking for public nodes in large graphs.
And PR #10428 fixed a transaction pool exhaustion issue when running Postgres with a limited number of connections.
BOLT spec compliance
LND now enforces that channel_update and node_announcement messages must have non-zero timestamps, as required by BOLT 7. Gossip messages with zero timestamps are rejected, and remote peers sending invalid channel_update messages will have their ban score incremented. PR #10469 made that happen.
Gossiper panic recovery
PR #10470 added panic recovery to gossiper message processing goroutines. If a logic error causes a panic during message processing, the gossiper can keep operating instead of crashing the entire subsystem. Panics are logged with full traces for debugging.
This is defensive programming. You don’t want a panic to kill the gossiper, because the gossiper keeps your view of the network up to date. Better to log the error and keep running.
Should you upgrade?
Yes.
This is a recommended upgrade for all LND operators, especially if you’re on v0.20.0-beta or planning to upgrade from v0.19.x.
Upgrade steps:
- Backup your channel database (always, before any upgrade)
- Download v0.20.1-beta from the GitHub releases page
- Verify signatures (GPG and OpenTimestamps are provided)
- Stop LND
- Replace the binary
- Start LND
No configuration changes are required unless you want to enable the new Postgres concurrency options.
If you’re upgrading from v0.19.x, you can safely jump directly to v0.20.1-beta. The backwards compatibility bug that affected v0.20.0-beta upgrades is fixed. However, if you’re using --db.use-native-sql with SQLite or Postgres, the graph migration from v0.20.0-beta will still run. This is optional but recommended for performance. See the v0.20.0-beta release notes for details on that migration.
Context: what v0.20.0-beta introduced
v0.20.0-beta (released November 20, 2025) was a major update that introduced native SQL support for the graph store. If you enable --db.use-native-sql, LND migrates the channel graph from the legacy KV store to SQLite or Postgres. This is a one-way migration that can take time on large graphs, but it improves performance.
v0.20.1-beta builds on that foundation. It’s a stability release, not a feature release. The focus is on fixing the bugs that early v0.20.0-beta adopters ran into.
Who contributed
Nine people fixed these issues in just under three months:
- Abdullahi Yunus
- bitromortac
- Elle Mouton
- ffranr
- Matt Morehouse (fuzz testing)
- Mohamed Awnallah
- Olaoluwa Osuntokun (Lightning Labs)
- Thiago Romão Barcala
- Yong Yu
- ziggie
Matt Morehouse’s fuzz testing work deserves a callout. Systematic fuzzing of Lightning implementations is finding real bugs before they hit production. That’s proactive security.
Adoption
Lightning Terminal v0.14.1-alpha packages LND v0.20.1-beta alongside Taproot Assets Daemon v0.7.1, Loop v0.31.8-beta, Pool v0.6.6-beta, and Faraday v0.2.16-alpha. This indicates Lightning Labs’ confidence in the stability of this release.
If you’re running Lightning Terminal, watch for that update.
Final thoughts
This isn’t a flashy release. There are no new features. But stability matters more than features when you’re running infrastructure that routes real money.
The backwards compatibility fix alone makes this worth upgrading. If you’re on v0.20.0-beta, the deadlock fixes and race condition patches are good reasons to move. And if you’re still on v0.19.x, the path is clear now.
Upgrade. Back up first. Then upgrade.
Sources
- LND v0.20.1-beta Release
- Release Notes (Full)
- Backwards Compatibility Fix (PR #10529)
- Gossiper Deadlock Fix (PR #10540)
- Source Node Race Fix (PR #10371)
- Timestamp Precision Fix (PR #10449)
- TLS Certificate Regeneration Fix (PR #10399)
- Mission Control Recovery Fix (PR #10383)
- Channel Graph Race Fixes (PR #10433)
- Disabled Channel Policy Fix (PR #10378)
- Address Deduplication Fix (PR #10341)
- LSP Detection Enhancement (PR #10396)
- Payment Secret Support (PR #10439)
- Postgres Concurrency Controls (PR #10394)
- Query Optimization (PR #10356)
- Transaction Pool Fix (PR #10428)
- Timestamp Enforcement (PR #10469)
- Panic Recovery (PR #10470)
- LND v0.20.0-beta Release
- Issue #10528 (Backwards Compatibility Bug)
- BOLT 7: Routing Gossip
Last updated: March 2, 2026