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:

Short answer

A 414 is a request-line error, not a body error. It means the URI (method + path + query string) exceeded a limit on the server/proxy — it has nothing to do with how much data is in the POST body. So if the hex were genuinely traveling in the body, the transaction’s size could not cause a 414. The presence of a 414 tells you the hex (or other long data) is ending up in the URL, or that an edge proxy is rejecting the request line.

That points at one of two things: the array trick isn’t actually taking the POST branch, or an HTTP layer in front of the API is generating the error.

What the bch-js code actually does

In sendRawTransaction() the branch is decided by the input type (raw-transactions.js, ~L453–540):

  • typeof hex === 'string' → GET
    GET ${restURL}full-node/rawtransactions/sendRawTransaction/${hex}
    → the hex goes into the URL. This is the only path in the function that can 414 on a large tx.
  • Array.isArray(hex) → POST
    POST ${restURL}full-node/rawtransactions/sendRawTransaction with data: { hexes }
    → the hex goes in the body. No URL growth.

So the array-wrapping trick exists precisely to avoid the GET path. If you’re still seeing 414, the GET branch is almost certainly the one being executed.

Why [hex] might not hit the POST branch:

  • The value isn’t a true array (e.g. a string, Buffer, typed array, or array-like object) — the typeof === 'string' check runs first.
  • A higher-level helper is unwrapping/flattening and calling sendRawTransaction(someString) internally (e.g. a wallet or TransactionBuilder-style helper), so your array never reaches this function as an array.
  • A different/older bch-js build or a mismatched bundle.

If it really is a POST

Then the 414 is being produced by the infrastructure in front of the server, e.g.:

  • nginx request-line limits (client_header_buffer_size / large_client_header_buffers, ~8 KB by default). Notably, bch-api’s own route-utils.js decodeError() has a case for errors “thrown by nginx (usually the SLPDB load balancer)”, confirming an nginx layer sits in the request path.
  • A CDN/WAF (Cloudflare returns 414 for over-long request lines) or Apache (LimitRequestLine, default ~8190 bytes).
  • An HTTP→HTTPS or trailing-slash redirect that folds the request into a longer URI.

Also note: the GET URL is roughly
https://.../v5/full-node/rawtransactions/sendRawTransaction/<hex>, so even a moderately large tx quickly blows past an 8 KB request-line buffer — exactly this failure mode.

Fast diagnostics

  1. Log error.config.method and error.config.url. If the URL ends in the hex → you’re on the GET branch, not POST.
  2. Inspect the 414 response body. A JSON body like {"error": ...} came from bch-api; a raw nginx/Apache HTML error page means the 414 was generated by the edge proxy, before it ever reached the API.
  3. Reproduce with curl, forcing body-only:
    curl -X POST https://api.fullstack.cash/v5/full-node/rawtransactions/sendRawTransaction \
      -H "Content-Type: application/json" \
      -d '{"hexes":["<your-hex>"]}'
    
  4. Confirm the server route exists — bch-api does register POST /sendRawTransaction → sendRawTransactionBulk (src/routes/v5/full-node/rawtransactions.js), which reads req.body.hexes, so body-only POSTs are supported.

Don’t confuse the 4xx codes

  • 414 – request URI too long
  • 413 – request body too large (nginx client_max_body_size)
  • 431 – request headers too large

One more note: the retry logic added in bch-js PR #290 only retries transient network errors (ECONNRESET/EPIPE/ETIMEDOUT/socket hang up), so a 414 is passed straight back to the caller — it won’t be masked or retried away.

Bottom line: the tx size isn’t the problem; the hex is reaching the URL (GET branch) or an edge proxy is rejecting the request line. Verify the outgoing method/URL first, and only raise proxy URI limits if you confirm a genuine body-bearing POST is still being rejected.

Sources: bch-js src/raw-transactions.js (the commit you linked); bch-api src/routes/v5/full-node/rawtransactions.js and src/util/route-utils.js; bch-js PR #290.


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


Write a comment