Q&A: I'm looking at the documentation for bch-js, which is available here: https://bc...

Block answers a tech-support question about I'm looking at the documentation for bch-js, which is available here: https://bch-js.fullstackcash.n...

Question:

I’m looking at the documentation for bch-js, which is available here:
https://bch-js.fullstackcash.net/#api-RawTransactions-sendRawTransaction

A user is complaining that they are trying to broadcast a large transaction using the bch-js RawTransactions.sendRawTransaction(). They are wrapping the hex string in an array ([hex]) in order to trigger the POST call. But they are reporting that they are getting 414 HTTP errors. If they are using the POST call and the large hex string is in the body, what would cause this 414 error?

Here is the source code for that function:
https://github.com/Permissionless-Software-Foundation/bch-js/blob/7649eeffec4034f0dcff1234ba0deef1c965acd9/src/raw-transactions.js#L453-L540


Answer:

I’ve now examined both the bch-js client code (at the commit you linked) and the corresponding server route in bch-api. Here’s the answer.

Short answer

A 414 URI Too Long is about the request line / URL, not the request body. The HTTP body is never part of the URI, so a large hex sitting in a POST body cannot, by itself, produce a 414 — at most you’d get a 413 Payload Too Large. So if the user is genuinely hitting the array→POST path with the hex in the body, a 414 is essentially impossible from the URL-length standpoint. The practical conclusion: the hex is still ending up in the URL — i.e., the request is actually going out as a GET, not the POST they believe.

Why this happens in bch-js

Look at the code you linked. sendRawTransaction has two very different code paths:

  • Single string hex → GET (the culprit):

    if (typeof hex === 'string') {
      const response = await this.axios.get(
        `${this.restURL}full-node/rawtransactions/sendRawTransaction/${hex}`
        ...
    

    The hex is interpolated directly into the URL path.

  • Array → POST:

    } else if (Array.isArray(hex)) {
      ... await this._postSendRawTransaction(hex)   // data: { hexes }
    

    _postSendRawTransaction sends POST {url, data: { hexes }} — a short URL with the hex in the JSON body.

So the GET branch is what puts a big hex into the URL. A large transaction hex (big multi-input CashToken/OP_RETURN transactions are easily several KB to tens of KB) blows past the reverse-proxy’s request-line cap (e.g., nginx large_client_header_buffers, default ~8 KB per buffer), and the proxy responds 414. This is the classic bch-js large-transaction gotcha.

Likely real-world causes

  1. The user isn’t actually hitting the POST branch. Even though they think they’re wrapping in an array, if the value passed is a plain string (or their bch-js version doesn’t include the array→POST path — this bulk POST is a relatively recent addition), the string branch fires and it becomes a GET with the hex in the URL → 414. Note the server only supports the POST route when it’s an actual array (req.body.hexes must be an array).
  2. Confirm with the server route. bch-api v5 does register both routes (I verified in src/routes/v5/full-node/rawtransactions.js):
    • GET /sendRawTransaction/:hexsendRawTransactionSingle
    • POST /sendRawTransactionsendRawTransactionBulk (body { "hexes": [...] })
      If the request were truly the POST, you’d get a 400/413/server error, not a 414.

What I’d advise the user to check/fix

  1. Verify the actual wire request (browser DevTools network tab, or a temporary axios interceptor logging method + url). Confirm it’s a POST to .../sendRawTransaction with a short URL and the hex inside the JSON body — not a GET with .../sendRawTransaction/<huge-hex>.
  2. Make sure they’re passing a real array so Array.isArray() is true, and that they’re on a bch-js build that has _postSendRawTransaction (i.e., the commit you linked or later).
  3. Use the array/POST form for large transactions. That’s exactly what it’s for. Note the server’s bulk route also enforces array-size limits (returns 400 "Array too large.") and broadcasts hexes serially.
  4. If they still need the single-string form against a server that only offers the GET endpoint, large transactions won’t fit — fall back to the POST endpoint, broadcast via node JSON-RPC directly, or another pushtx service.

Sources

Key takeaway: 414 means “your URL is too long,” so the hex is going through the GET/URL path. If they can confirm the POST + body is really being used, the status code they’d expect for a too-large body is 413, not 414.


Public Q&A mirror from the Block tech-support bot.


Write a comment