What changed, and why it matters
This patch teaches LND to recognize a second type of Bitcoin network fee-rejection error ('minimum relay fee not met') alongside the one it already handled ('mempool minimum fee not met'). Without the change, transactions rejected for the new reason would not be retried or fee-bumped automatically, potentially leaving channel-closing or penalty transactions stuck instead of being rebroadcast with a higher fee.
Treat as a reliability/robustness fix rather than an active vulnerability. Review whether other fee-rejection error variants from btcd/btcwallet are still unhandled, and verify that fee-bumper retry limits prevent runaway fee escalation.
Security signals we found
Unrecognized fee-rejection error could stop transaction rebroadcast, affecting timeliness of justice/penalty transactions
Patch adds explicit handling for a new fee error class in broadcast and RBF paths
No direct memory-safety or cryptographic bug visible in diff
Evidence from the diff
The commit expands error matching in three places to include chain.ErrMinRelayFeeNotMet wherever chain.ErrMempoolMinFeeNotMet was already handled. In config_builder.go the new error is mapped to a retryable pushtx.BroadcastError. In lnwallet/btcwallet/btcwallet.go it is wrapped as lnwallet.ErrMempoolFee. In sweep/fee_bumper.go it is treated as a signal to raise the fee rate and retry RBF. The change is defensive: it prevents a previously unhandled fee error from breaking automatic rebroadcast/fee-bump logic.
Changed components
config_builder.go:broadcastErrorMapperlnwallet/btcwallet/btcwallet.go:mapRpcclientErrorsweep/fee_bumper.go:createRBFCompliantTxInspect captured patch +14 / −5
diff --git a/config_builder.go b/config_builder.go
index 7729b51..6f9cb1f 100644
--- a/config_builder.go
+++ b/config_builder.go
@@ -1807,8 +1807,11 @@ func broadcastErrorMapper(err error) error {
// in the first place are rebroadcasted despite of their backend error.
// Mempool conditions change over time so it makes sense to retry
// publishing the transaction. Moreover we log the detailed error so the
- // user can intervene and increase the size of his mempool.
- case errors.Is(err, chain.ErrMempoolMinFeeNotMet):
+ // user can intervene and increase the size of his mempool or increase
+ // his min relay fee configuration.
+ case errors.Is(err, chain.ErrMempoolMinFeeNotMet),
+ errors.Is(err, chain.ErrMinRelayFeeNotMet):
+
ltndLog.Warnf("Error while broadcasting transaction: %v", err)
returnErr = &pushtx.BroadcastError{
diff --git a/lnwallet/btcwallet/btcwallet.go b/lnwallet/btcwallet/btcwallet.go
index 7762dc5..a29139d 100644
--- a/lnwallet/btcwallet/btcwallet.go
+++ b/lnwallet/btcwallet/btcwallet.go
@@ -1133,7 +1133,9 @@ func mapRpcclientError(err error) error {
// If the wallet reports that fee requirements for accepting the tx
// into mempool are not met, convert it to our internal ErrMempoolFee
// and return.
- case errors.Is(err, chain.ErrMempoolMinFeeNotMet):
+ case errors.Is(err, chain.ErrMempoolMinFeeNotMet),
+ errors.Is(err, chain.ErrMinRelayFeeNotMet):
+
return fmt.Errorf("%w: %v", lnwallet.ErrMempoolFee, err.Error())
}
diff --git a/sweep/fee_bumper.go b/sweep/fee_bumper.go
index a23213f..e0d5d75 100644
--- a/sweep/fee_bumper.go
+++ b/sweep/fee_bumper.go
@@ -565,7 +565,10 @@ func (t *TxPublisher) createRBFCompliantTx(
// If the error indicates the fees paid is not enough, we will
// ask the fee function to increase the fee rate and retry.
- case errors.Is(err, lnwallet.ErrMempoolFee):
+ case errors.Is(err, lnwallet.ErrMempoolFee),
+ errors.Is(err, chain.ErrMinRelayFeeNotMet),
+ errors.Is(err, chain.ErrMempoolMinFeeNotMet):
+
// We should at least start with a feerate above the
// mempool min feerate, so if we get this error, it
// means something is wrong earlier in the pipeline.
@@ -574,7 +577,8 @@ func (t *TxPublisher) createRBFCompliantTx(
fallthrough
- // We are not paying enough fees so we increase it.
+ // We are not paying enough fees to RBF a previous tx, so we
+ // increase it.
case errors.Is(err, chain.ErrInsufficientFee):
increased := false
Why this scored 40/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.