Description
Every RLP decode failure on eth_sendRawTransaction is reported with code -32000 (InvalidInput) and the literal message "Invalid RLP.", regardless of the actual cause. Per the JSON-RPC 2.0 spec, Reth, and Besu, parameter-validation failures (which malformed RLP is) should be -32602 (InvalidParams). Canonical Geth + Erigon currently emit -32000 for this axis; we deliberately diverge from them to align with the spec.
This supersedes #11206 (closed; PR #11325 never merged).
The original closing PR hard-coded a single Geth string that no longer matches any current Geth response — the right fix is the code change plus a Geth-inspired but not byte-identical message.
| Input |
NM |
Geth |
"0xc0" |
-32000 / "Invalid RLP." |
-32000 / "rlp: too few elements for types.LegacyTx" |
"0xd4" |
-32000 / "Invalid RLP." |
-32000 / "rlp: value size exceeds available input length" |
"0x" |
-32000 / "Invalid RLP." |
-32000 / "typed transaction too short" |
"0x09c0" (unknown type) |
-32000 / "Invalid RLP." |
-32000 / "transaction type not supported" |
"0x03c0" (EIP-4844) |
-32000 / "Invalid RLP." |
-32000 / "unexpected EOF" |
"0x04c0" (EIP-7702) |
-32000 / "Invalid RLP." |
-32000 / "rlp: too few elements for types.SetCodeTx" |
Note: NM and canonical Geth currently agree on the code (-32000); only the message differs. Public Geth-labelled providers tested (Infura, publicnode, 1rpc.io) all wrap this to -32602/-32600 at their edge. The fix proposed here moves NM to -32602 to align with spec + Reth + Besu
13 distinct inputs in the rpc-tests fixture PR corpus (test_01-06, 12-16, 20, 21) reach the same code path and all collapse to the same vague NM response.
Steps to Reproduce
{
"jsonrpc": "2.0",
"method": "eth_sendRawTransaction",
"params": ["0xd4"],
"id": 1
}
Expected
-32602 rejection, with a descriptive message (Geth-inspired but not required to match byte-for-byte, see this PR for more).
Actual (Nethermind v1.38.0+c07a4d65)
{"jsonrpc":"2.0","error":{"code":-32000,"message":"Invalid RLP."},"id":1}
Fix Locations
src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs:369-372 — the catch (RlpException) block at :369 (the Fail("Invalid RLP.", ErrorCodes.TransactionRejected) is at :371). Change ErrorCodes.TransactionRejected → ErrorCodes.InvalidParams; replace the literal "Invalid RLP." with "transaction could not be decoded: " + e.Message so the underlying RLP cause comes through.
src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.cs:1908-1914 — Send_raw_transaction_returns_invalid_rlp_for_empty_list currently pins the old code/message via Is.EqualTo; switch to Does.Contain against the new prefix.
EthRpcModuleTests.cs:1916-1931 — SendRawTransactionSyncFailureCases source (:1929-1931) yields TestCaseData("c0", null, ErrorCodes.TransactionRejected, "Invalid RLP") for the sync variant; update to InvalidParams + new fragment.
Notes
- rpc-tests fixtures
test_01-06, 12-16, 20, 21 in PR pin {"code": -32602, "message": null} via the new per-fixture code-only sentinel. 13 fixtures currently FAIL against NM; all 13 flip to PASS when this fix lands.
Description
Every RLP decode failure on
eth_sendRawTransactionis reported with code-32000(InvalidInput) and the literal message"Invalid RLP.", regardless of the actual cause. Per the JSON-RPC 2.0 spec, Reth, and Besu, parameter-validation failures (which malformed RLP is) should be-32602(InvalidParams). Canonical Geth + Erigon currently emit-32000for this axis; we deliberately diverge from them to align with the spec.This supersedes #11206 (closed; PR #11325 never merged).
The original closing PR hard-coded a single Geth string that no longer matches any current Geth response — the right fix is the code change plus a Geth-inspired but not byte-identical message.
"0xc0"-32000 / "Invalid RLP."-32000 / "rlp: too few elements for types.LegacyTx""0xd4"-32000 / "Invalid RLP."-32000 / "rlp: value size exceeds available input length""0x"-32000 / "Invalid RLP."-32000 / "typed transaction too short""0x09c0"(unknown type)-32000 / "Invalid RLP."-32000 / "transaction type not supported""0x03c0"(EIP-4844)-32000 / "Invalid RLP."-32000 / "unexpected EOF""0x04c0"(EIP-7702)-32000 / "Invalid RLP."-32000 / "rlp: too few elements for types.SetCodeTx"Note: NM and canonical Geth currently agree on the code (
-32000); only the message differs. Public Geth-labelled providers tested (Infura, publicnode, 1rpc.io) all wrap this to-32602/-32600at their edge. The fix proposed here moves NM to-32602to align with spec + Reth + Besu13 distinct inputs in the rpc-tests fixture PR corpus (
test_01-06, 12-16, 20, 21) reach the same code path and all collapse to the same vague NM response.Steps to Reproduce
{ "jsonrpc": "2.0", "method": "eth_sendRawTransaction", "params": ["0xd4"], "id": 1 }Expected
-32602rejection, with a descriptive message (Geth-inspired but not required to match byte-for-byte, see this PR for more).Actual (Nethermind v1.38.0+c07a4d65)
{"jsonrpc":"2.0","error":{"code":-32000,"message":"Invalid RLP."},"id":1}Fix Locations
src/Nethermind/Nethermind.JsonRpc/Modules/Eth/EthRpcModule.cs:369-372— thecatch (RlpException)block at:369(theFail("Invalid RLP.", ErrorCodes.TransactionRejected)is at:371). ChangeErrorCodes.TransactionRejected→ErrorCodes.InvalidParams; replace the literal"Invalid RLP."with"transaction could not be decoded: " + e.Messageso the underlying RLP cause comes through.src/Nethermind/Nethermind.JsonRpc.Test/Modules/Eth/EthRpcModuleTests.cs:1908-1914—Send_raw_transaction_returns_invalid_rlp_for_empty_listcurrently pins the old code/message viaIs.EqualTo; switch toDoes.Containagainst the new prefix.EthRpcModuleTests.cs:1916-1931—SendRawTransactionSyncFailureCasessource (:1929-1931) yieldsTestCaseData("c0", null, ErrorCodes.TransactionRejected, "Invalid RLP")for the sync variant; update toInvalidParams+ new fragment.Notes
test_01-06, 12-16, 20, 21in PR pin{"code": -32602, "message": null}via the new per-fixture code-only sentinel. 13 fixtures currently FAIL against NM; all 13 flip to PASS when this fix lands.