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:
- Start the same-chain lab:
go run ./cmd/wasp-lab \
-config env/config.yaml \
-inventory env/inventory.samechain.yaml \
-tier samechain up
- 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
- 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
- Check:
evidence/artifacts/bodies-review-refresh-20260417/summary.tsv
evidence/artifacts/receipts-review-refresh-20260417/summary.tsv
General reproduction without WireWasp:
- Run Nethermind on a devnet and connect with a devp2p test peer that can speak RLPx and
eth/69.
- Session A: complete RLPx hello and ETH status.
- Session A: send a valid
GetBlockBodies request for one unavailable hash. Close the session after the request path.
- Session B: immediately open a fresh RLPx+
eth/69 session and request the current head body.
- Repeat the same pattern with
GetReceipts: first request one unavailable hash, then use a fresh session to request receipts for the current head.
- 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
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:
GetBlockBodieswith one unknown hashGetReceiptswith one unknown hashIn 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:
GetBlockBodiesfresh-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-recoveryGetReceiptsfresh-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-recoveryevidence/artifacts/bodies-review-refresh-20260417/summary.tsvevidence/artifacts/receipts-review-refresh-20260417/summary.tsvGeneral reproduction without WireWasp:
eth/69.GetBlockBodiesrequest for one unavailable hash. Close the session after the request path.eth/69session and request the current head body.GetReceipts: first request one unavailable hash, then use a fresh session to request receipts for the current head.Actual behavior
For
GetBlockBodies, Nethermind failed all four refreshed testcase variants:testcase.len1-fresh-recovery: NethermindRECOVERY_FAILED_FRESH_CONNECTION; comparators 4/4RESPONDED_VALID,block_bodies request=3201 count=1testcase.len255-fresh-recovery: NethermindRECOVERY_FAILED_FRESH_CONNECTION; comparators 4/4RESPONDED_VALID,block_bodies request=3455 count=1testcase.len255-fresh-recovery-delay: NethermindRECOVERY_FAILED_FRESH_CONNECTION; comparators 4/4RESPONDED_VALID,block_bodies request=3455 count=1testcase.len255-read-primary-fresh-recovery: NethermindRECOVERY_FAILED_FRESH_CONNECTION; comparators 4/4RESPONDED_VALID,block_bodies request=3455 count=1For
GetReceipts, Nethermind failed the minimized len=1 case:testcase.len1-getreceipts-fresh-recovery: NethermindRECOVERY_FAILED_FRESH_CONNECTION; comparators 4/4RESPONDED_VALID,receipts request=3201 count=1In the minimized len=1 rows, the failure summary was
eth pre-response code=0on the fresh session. The node remained reachable; this evidence does not show a crash or persistent node-wide outage.Expected behavior
A prior valid
GetBlockBodiesorGetReceiptsrequest 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):
Nethermind/v1.36.2+f5507dec/linux-x64/dotnet10.0.1nethermind/nethermind:latest12345Additional context
This looks broader than a single request-family bug because both
GetBlockBodiesandGetReceiptsreproduce 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.tsvevidence/artifacts/bodies-review-refresh-20260417/summary.jsonevidence/artifacts/bodies-review-refresh-20260417/*nethermind*.jsonevidence/artifacts/bodies-review-refresh-20260417/*geth*.jsonevidence/artifacts/bodies-review-refresh-20260417/*reth*.jsonevidence/artifacts/bodies-review-refresh-20260417/*erigon*.jsonevidence/artifacts/bodies-review-refresh-20260417/*besu*.jsonevidence/artifacts/receipts-review-refresh-20260417/summary.tsvevidence/artifacts/receipts-review-refresh-20260417/summary.jsonevidence/artifacts/receipts-review-refresh-20260417/*nethermind*.jsonevidence/artifacts/receipts-review-refresh-20260417/*geth*.jsonevidence/artifacts/receipts-review-refresh-20260417/*reth*.jsonevidence/artifacts/receipts-review-refresh-20260417/*erigon*.jsonevidence/artifacts/receipts-review-refresh-20260417/*besu*.jsonevidence/config/env.config.yamlevidence/config/inventory.samechain.yamlevidence/testcases/bodies/*.yamlevidence/testcases/receipts/*.yamlevidence.zip