exceed maximum block range: 50000 (and every other eth_getLogs range error)
What it means
The node refused to scan that many blocks in one eth_getLogs call. Every provider caps the span between fromBlock and toBlock, because an unbounded log scan is one of the most expensive queries a node can be asked to run. The number in the message is that node's cap, and it is a property of the node, not of the chain: two nodes behind the same endpoint can answer the same request with different caps (Cronos did exactly that).
The caps we observed range from 150 blocks to 100,000. At 0.25-second blocks, 10,000 blocks is 40 minutes of chain history; at 12-second blocks it is 33 hours. Size chunks in blocks for the chain you are on, not in wall-clock time.
The exact messages, and where we saw them
Returned by real upstream nodes when we triggered this error on 2026-09-24 through our endpoint on each chain we serve.
exceed maximum block range: 50000exceed maximum block range: 10000-32701. Seen on 1 chain: Polygon.query exceeds max block range 1000-32602. Seen on 1 chain: Hyperliquid.eth_getLogs is limited to 150 blocks per request; requested 100001 (… to …). Split the query into smaller ranges.-32602. Seen on 1 chain: BNB Smart Chain.eth_getLogs range of 100001 blocks exceeds the 500-block limit for this plan; split the request into ranges of …maximum [from, to] blocks distance: 10000-32000. Seen on 1 chain: Cronos. (seen from one Cronos upstream while another answered with the 50,000 message)How to fix it
- Split the range into chunks no larger than the smallest cap you might hit, and walk forward. When a chunk still fails with a range error, halve it and retry that chunk.
- Always pass an
address(and topics where you can). A narrower filter is cheaper for the node and some providers only apply the larger cap to filtered queries. - For historical backfills, record the last block you finished so a restart resumes instead of rescanning.
async function getLogsChunked(client, filter, from: bigint, to: bigint, step = 2_000n) {
const out = [];
for (let start = from; start <= to; ) {
const end = start + step - 1n > to ? to : start + step - 1n;
try {
out.push(...(await client.getLogs({ ...filter, fromBlock: start, toBlock: end })));
start = end + 1n;
} catch (e) {
if (step === 1n || !/range|too large|limit|distance/i.test(String(e))) throw e;
step = step / 2n; // node cap is smaller than our chunk: halve and retry this chunk
}
}
return out;
}