Skip to content

Nethermind returns placeholder bodies and receipts for unknown block hashes #11231

@N0zoM1z0

Description

@N0zoM1z0

Description

Nethermind returns one empty response item for GetBlockBodies and GetReceipts requests whose requested hash is not a known block. The minimal same-chain case uses the all-zero hash, and the same behavior also reproduced with unknown non-zero hashes in boundary hunting.

For GetBlockBodies, an unavailable block can be omitted from the response. For GetReceipts, responses should preserve request order and stop at the first unavailable block. In both cases, returning a placeholder entry for an unknown hash makes the response look like data for a known empty block.

The issue was found with WireWasp, our own devp2p/ETH wire fuzzer and replay harness. The attached bundle includes the exact WireWasp cases, run configuration, raw request/response hex, replay results, JSON-RPC control, and comparator output from Geth, Reth, Erigon, and Besu.

Steps to Reproduce

With the attached WireWasp reproduction bundle:

  1. Start the same-chain lab:
go run ./cmd/wasp-lab \
  -config env/config.yaml \
  -inventory env/inventory.samechain.yaml \
  -tier samechain up
  1. Run the refreshed differential replay:
TARGETS='geth-s reth-s erigon-s besu-s nethermind-s' \
OUT_DIR=output/regressions/review-refresh-nethermind-zero-hash-20260417 \
scripts/regress-finding.sh \
  findings/confirmed/2026-04-11-nethermind-zero-hash-bodies-receipts
  1. Check evidence/artifacts/review-refresh-20260417/summary.tsv.

General reproduction without WireWasp:

  1. Run Nethermind on a devnet and connect with any devp2p test peer that can speak RLPx and eth/69.
  2. Complete RLPx hello and ETH status.
  3. Send GetBlockBodies with request id 1 and one hash: 0x0000000000000000000000000000000000000000000000000000000000000000.
  4. Repeat on a fresh session with GetReceipts for the same hash.
  5. Use JSON-RPC eth_getBlockByHash for the same hash as a control. In our run it returned null.
  6. Compare against Geth/Reth/Erigon/Besu on the same genesis.

Actual behavior

Nethermind returned one item for each unknown-hash request:

  • GetBlockBodies: block_bodies request=1 count=1
  • GetReceipts: receipts request=1 count=1

The raw minimized request payload for both cases is:

e301e1a00000000000000000000000000000000000000000000000000000000000000000

The observed Nethermind response payload is:

c301c1c0

On the same chain, Geth, Reth, Erigon, and Besu returned count 0 for both request families. JSON-RPC on the Nethermind node reported the all-zero hash as absent:

{"jsonrpc":"2.0","result":null,"id":1}

Expected behavior

For an unknown block hash, GetBlockBodies should not include a body entry for that hash. GetReceipts should not include a receipt list for an unavailable block; if a requested block is missing, the response should end at that point rather than adding a placeholder item.

Screenshots

Not applicable. This is a wire-protocol response issue. The bundle includes raw RLP payloads, transcripts, JSON replay results, and comparator summaries.

Desktop (please complete the following information):

  • Operating System: Linux
  • Version: Nethermind/v1.36.2+f5507dec/linux-x64/dotnet10.0.1
  • Installation Method: Docker image nethermind/nethermind:latest
  • Consensus Client: not used in this devnet reproduction
  • Network: same-chain devnet, network id 12345
  • Genesis hash: 0x10bf86bf4072831c4648c9585d22c9426d998fc31962029dc57aa8aa0594751b
  • Comparators: Geth v1.17.1, Reth v1.11.3, Erigon v3.1.0, Besu v26.2.0

Additional context

This is a high-confidence semantic issue, but I am reporting it as a normal protocol correctness bug rather than a security vulnerability. Boundary probes in the attached material show the behavior is not limited to the all-zero hash: unknown non-zero hashes also returned one empty body/receipt item per requested hash on Nethermind, while comparator clients returned empty responses.

Logs

The attached zip contains:

  • evidence/artifacts/review-refresh-20260417/summary.tsv
  • evidence/artifacts/review-refresh-20260417/summary.json
  • evidence/artifacts/review-refresh-20260417/*nethermind*.json
  • evidence/artifacts/samechain-block-bodies/transcript/*.hex
  • evidence/artifacts/samechain-block-bodies/result.json
  • evidence/artifacts/samechain-receipts/transcript/*.hex
  • evidence/artifacts/samechain-receipts/result.json
  • evidence/artifacts/samechain-lab/status.json
  • evidence/config/env.config.yaml
  • evidence/config/inventory.samechain.yaml
  • evidence/testcases/testcase.block-bodies.min.yaml
  • evidence/testcases/testcase.receipts.min.yaml

evidence.zip

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions