keysend: increase assumed final_cltv_expiry to 42 (to match LDK).
What changed, and why it matters
This change fixes a compatibility issue in the `keysend` payment feature. Core Lightning was assuming a lower safety margin (22 blocks) for the final recipient's deadline than LDK/Rust-Lightning actually requires (42 blocks). When sending spontaneous payments to LDK nodes, this mismatch could cause the payment to be rejected or fail. The patch simply raises the assumed value to match LDK, improving interoperability. It is not a vulnerability that lets an attacker steal funds, but it is a reliability/security-adjacent fix for payment routing.
Apply the patch. No additional hardening is required. Operators using `keysend` to pay LDK nodes should upgrade to avoid payment failures.
Security signals we found
Interoperability fix for final CLTV expiry mismatch
Could cause payment failure/rejection when sending to LDK nodes
No memory corruption, authentication bypass, or cryptographic weakness introduced
Reported by external contributor and acknowledged with Fixes tag
Evidence from the diff
In plugins/keysend.c, the min_final_cltv_expiry used for spontaneous keysend payments was increased from 22 to 42. The old value matched an earlier Rust-Lightning default, but LDK now requires a higher minimum final CLTV expiry. If the assumed value is too low, the receiving node may reject the HTLC because it does not allow enough blocks for it to claim the funds. This is a one-line constant update with a comment update; it does not change parsing logic or add new attack surface.
Changed components
plugins/keysend.cJSON-RPC `keysend` commandInspect captured patch +2 / −2
diff --git a/plugins/keysend.c b/plugins/keysend.c
index 6c02dc8f..92246bec 100644
--- a/plugins/keysend.c
+++ b/plugins/keysend.c
@@ -226,8 +226,8 @@ static struct command_result *json_keysend(struct command *cmd, const char *buf,
* caller to provide keysend secret */
p->our_amount = p->final_amount = *msat;
p->routes = tal_steal(p, hints);
- // 22 is the Rust-Lightning default and the highest minimum we know of.
- p->min_final_cltv_expiry = 22;
+ // 42 is the Rust-Lightning default and the highest minimum we know of.
+ p->min_final_cltv_expiry = 42;
p->features = NULL;
p->invstring = NULL;
/* Don't try to use invstring to hand to sendonion! */
Why this scored 35/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.