Start with a known event
A valid eth_getLogs query can return an empty array. Find one transaction receipt containing the event you expected, and treat that receipt as a test fixture. The address and topics in the actual log are more reliable than an address copied from a contract implementation page.
Remove filters before adding them
{"jsonrpc":"2.0","id":1,"method":"eth_getLogs","params":[{"fromBlock":"0x100","toBlock":"0x100","address":"CONTRACT_ADDRESS"}]}Use the real block containing your fixture. Begin with the emitting address and an explicit one-block window. Once the event appears, add topic constraints one position at a time. Do not use this placeholder address as a production request.
Check the filter semantics
- Verify eth_chainId on the same endpoint. Identical addresses on different chains refer to independent state.
- Use the log-emitting address. A proxy executing implementation code can emit logs under the proxy address.
- Calculate topic zero from the canonical event signature, including complete types. Anonymous events follow different topic layout rules.
- Only indexed arguments are topics. Non-indexed arguments must be decoded from the data field after retrieval.
Scale a working query
After the fixture passes, widen the block range in bounded windows and checkpoint the last completed range. Distinguish a genuine empty result from an HTTP timeout, JSON-RPC error or provider range restriction. Those failures need retries or smaller requests; treating them as zero events silently creates gaps in your index.