RPC error HTTP 413: Request body over the 64 KiB limit

Last updated:

At a glance

Error details
PropertyValue
Applies toEvery network, HTTP and WebSocket
HTTP status413
error valuesbatch_too_large (array), request_too_large (object)
Limit64 KiB; 4 MiB on Robinhood Chain
Raised by planNo: identical for every key
Counts whitespaceYes: the limit is on the raw body
Standard nameRFC 9110 calls 413 Content Too Large

Cause

Every JSON-RPC element is gated by method and plan, so the gateway has to read the whole body before forwarding it. It reads up to 64 KiB, or 4 MiB on Robinhood Chain, and whitespace counts. A body above that cannot be inspected safely, so it is refused rather than passed on unchecked. The usual cause is a batch built by an indexer or a multicall helper that grew with its input: the code works in tests and starts failing when a real block arrives with more receipts or logs to fetch.

Solution

  1. Check the error field: batch_too_large for an array body, request_too_large for a single JSON-RPC object.
  2. Split the batch into smaller arrays and send them one after another. Measure the serialized size in bytes, not the element count.
  3. Remove what you do not need from the body: long eth_getLogs address lists are a common way to fill 64 KiB with a single element.
  4. Use a method that returns a block's data in one call where the network offers one, such as eth_getBlockReceipts, instead of one element per transaction.

Split by bytes

A count-based chunker is what breaks here: 500 small elements fit and 500 large ones do not. Build chunks against a byte budget, leaving headroom for the array brackets and commas.

const LIMIT = 60 * 1024; // stay under 64 KiB
const chunks = [[]];
let size = 2;
for (const call of calls) {
  const bytes = new TextEncoder().encode(JSON.stringify(call)).length + 1;
  if (size + bytes > LIMIT) { chunks.push([]); size = 2; }
  chunks.at(-1).push(call);
  size += bytes;
}

When a batch is the wrong shape

If you keep hitting this while reading whole blocks, the batch may be the wrong tool. On Solana, a filtered Yellowstone gRPC stream delivers what you would otherwise poll for. On EVM networks, eth_getLogs with a narrow topic filter usually replaces a batch of per-transaction receipt reads.

Example

{
  "error": "batch_too_large",
  "message": "Batch body exceeds the 64 KiB inspection limit; split the batch into smaller requests",
  "chain": "base"
}

FAQ

How many requests fit in 64 KiB?
It depends on the serialized size of each element. A bare eth_blockNumber element is about 65 bytes, while an eth_getLogs filter with many addresses can be several kilobytes. Measure bytes, not items.
Does a higher plan raise the limit?
No. It is an inspection limit on the gateway, the same on every plan. Plans change request rates, not body size.
Does splitting a batch cost more?
No. A batch of N requests already costs N requests against your RPS budget, so splitting changes when they are sent, not how many are counted.