Skip to content

Nethermind fresh-session recovery can fail after valid GetBlockBodies/GetReceipts requests for unavailable data #11233

@N0zoM1z0

Description

@N0zoM1z0

Description

Nethermind appears to have a fresh-session lifecycle issue after a previous valid ETH request for unavailable data. The current minimal evidence covers two request families:

  • GetBlockBodies with one unknown hash
  • GetReceipts with one unknown hash

In both variants, a first session sends a valid request, then a second fresh session immediately tries to complete a normal status + recovery request. Geth, Reth, Erigon, and Besu return the expected fresh recovery response. Nethermind stays process/RPC/TCP healthy, but the fresh session does not complete the expected ETH status/recovery path.

The issue was found with WireWasp, our own devp2p/ETH wire fuzzer and replay harness.

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 GetBlockBodies fresh-session regression:
TARGETS='geth-s reth-s erigon-s besu-s nethermind-s' \
OUT_DIR=output/regressions/review-refresh-nethermind-bodies-20260417 \
scripts/regress-finding.sh \
  findings/open/2026-04-16-nethermind-valid-large-getblockbodies-fresh-recovery
  1. Run the GetReceipts fresh-session regression:
TARGETS='geth-s reth-s erigon-s besu-s nethermind-s' \
OUT_DIR=output/regressions/review-refresh-nethermind-receipts-20260417 \
scripts/regress-finding.sh \
  findings/open/2026-04-16-nethermind-getreceipts-fresh-recovery
  1. Check:
  • evidence/artifacts/bodies-review-refresh-20260417/summary.tsv
  • evidence/artifacts/receipts-review-refresh-20260417/summary.tsv

General reproduction without WireWasp:

  1. Run Nethermind on a devnet and connect with a devp2p test peer that can speak RLPx and eth/69.
  2. Session A: complete RLPx hello and ETH status.
  3. Session A: send a valid GetBlockBodies request for one unavailable hash. Close the session after the request path.
  4. Session B: immediately open a fresh RLPx+eth/69 session and request the current head body.
  5. Repeat the same pattern with GetReceipts: first request one unavailable hash, then use a fresh session to request receipts for the current head.
  6. Compare with other clients on the same chain.

Actual behavior

For GetBlockBodies, Nethermind failed all four refreshed testcase variants:

  • testcase.len1-fresh-recovery: Nethermind RECOVERY_FAILED_FRESH_CONNECTION; comparators 4/4 RESPONDED_VALID, block_bodies request=3201 count=1
  • testcase.len255-fresh-recovery: Nethermind RECOVERY_FAILED_FRESH_CONNECTION; comparators 4/4 RESPONDED_VALID, block_bodies request=3455 count=1
  • testcase.len255-fresh-recovery-delay: Nethermind RECOVERY_FAILED_FRESH_CONNECTION; comparators 4/4 RESPONDED_VALID, block_bodies request=3455 count=1
  • testcase.len255-read-primary-fresh-recovery: Nethermind RECOVERY_FAILED_FRESH_CONNECTION; comparators 4/4 RESPONDED_VALID, block_bodies request=3455 count=1

For GetReceipts, Nethermind failed the minimized len=1 case:

  • testcase.len1-getreceipts-fresh-recovery: Nethermind RECOVERY_FAILED_FRESH_CONNECTION; comparators 4/4 RESPONDED_VALID, receipts request=3201 count=1

In the minimized len=1 rows, the failure summary was eth pre-response code=0 on the fresh session. The node remained reachable; this evidence does not show a crash or persistent node-wide outage.

Expected behavior

A prior valid GetBlockBodies or GetReceipts request for unavailable data should not affect a later fresh session. The fresh session should complete normal RLPx/ETH status and return the requested current-head body or receipts, or close cleanly according to peer policy. It should not leave the next session in a failed recovery state.

Screenshots

Not applicable. This is a wire-protocol replay issue. The bundle includes structured replay results, per-client logs, testcases, and lab configuration.

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
  • Comparators: Geth v1.17.1, Reth v1.11.3, Erigon v3.1.0, Besu v26.2.0

Additional context

This looks broader than a single request-family bug because both GetBlockBodies and GetReceipts reproduce the same immediate fresh-session failure pattern. The current evidence supports a normal session lifecycle / availability-hardening issue. It does not yet support a stronger claim such as persistent denial of service.

Logs

The attached zip contains:

  • evidence/artifacts/bodies-review-refresh-20260417/summary.tsv
  • evidence/artifacts/bodies-review-refresh-20260417/summary.json
  • evidence/artifacts/bodies-review-refresh-20260417/*nethermind*.json
  • evidence/artifacts/bodies-review-refresh-20260417/*geth*.json
  • evidence/artifacts/bodies-review-refresh-20260417/*reth*.json
  • evidence/artifacts/bodies-review-refresh-20260417/*erigon*.json
  • evidence/artifacts/bodies-review-refresh-20260417/*besu*.json
  • evidence/artifacts/receipts-review-refresh-20260417/summary.tsv
  • evidence/artifacts/receipts-review-refresh-20260417/summary.json
  • evidence/artifacts/receipts-review-refresh-20260417/*nethermind*.json
  • evidence/artifacts/receipts-review-refresh-20260417/*geth*.json
  • evidence/artifacts/receipts-review-refresh-20260417/*reth*.json
  • evidence/artifacts/receipts-review-refresh-20260417/*erigon*.json
  • evidence/artifacts/receipts-review-refresh-20260417/*besu*.json
  • evidence/config/env.config.yaml
  • evidence/config/inventory.samechain.yaml
  • evidence/testcases/bodies/*.yaml
  • evidence/testcases/receipts/*.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