Skip to content

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

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions