Skip to content

xpay: "Could not create payment onion: path too long!" on BOLT12 offers with large embedded TLVs (has FIXME) #9156

@vincenzopalazzo

Description

@vincenzopalazzo

Summary

When using xpay (and the surrounding payment plugins: renepay, askrene) to pay certain BOLT12 offers that carry large amounts of embedded data in their TLVs, xpay fails during onion construction with:

Could not create payment onion: path too long!

(with RPC error code 209 / PAY_UNSPECIFIED_ERROR).

The failure originates here:

https://github.com/ElementsProject/lightning/blob/master/plugins/xpay/xpay.c (around the do_inject function)

onion = create_onion(tmpctx, attempt, effective_bheight);
/* FIXME: Handle this better! */
if (!onion) {
    payment_give_up(aux_cmd, attempt->payment, PAY_UNSPECIFIED_ERROR,
        "Could not create payment onion: path too long!");
    return command_still_pending(aux_cmd);
}

The underlying cause is create_onionpacket(...) returning NULL when sphinx_path_payloads_size(sp) > ROUTING_INFO_SIZE.

Observed symptoms

  • The BOLT12 offers in question contain long invoice / offer metadata (hundreds of bytes of extra TLV data for payout tracking / recipient verification). This inflates the final serialized onion far beyond what a "normal length" route would use.
  • Route selection still proposes paths that later fail at the onion creation step.
  • In the same payment attempts we also saw many plugin-cln-renepay failures with code=202 "Malformed error reply" and very large onionreply blobs.
  • The node in question has very low channel count (only 2 active channels), which makes longer routes more common and the size limit easier to hit.
  • The error was surfaced to end users via a higher-level plugin (cln4go-plugin doing custom "ocean-pay" logic) during real production Lightning payout processing.

Steps to reproduce (conceptual)

  1. Have a node with limited channels.
  2. Attempt to pay a BOLT12 offer (lni1... / lno1...) whose encoded invoice/offer contains substantial extra TLV data.
  3. xpay / the payment attempt reaches create_onion → size check fails.

Expected behavior

  • Either the route finder (askrene + xpay/renepay) should account for the final serialized onion size (including extra BOLT12 TLVs) when selecting paths, or
  • xpay should handle the failure more gracefully (try a shorter route / more parts / clearer error with hop count + payload size, etc.), and
  • the error message returned to the caller / user should be more actionable than the current generic "path too long".

Version / environment

  • Observed on a custom/modded build based on v26.04 (and v25 on another instance)
  • Using xpay, renepay, askrene, plus custom BOLT12 handling on top (cln4go-plugin)
  • Full log excerpts and the exact failing offer (with tracking ID in the offer description) available if needed for reproduction.

Additional context

This was discovered while debugging a user-facing payout error on an experimental Ocean.xyz Lightning node (el.ocean.xyz).

The FIXME: Handle this better! comment suggests this case was already known to be suboptimal.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type::BugAn error, flaw, or fault that produces an incorrect or unexpected resultpay-pluginpluginrouting

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions