For the complete documentation index, see llms.txt
Decode 1010 transaction rejection errors
Resolve 1010 Invalid Transaction responses by decoding the inner Custom error: N value into a Midnight ledger error variant.
Understand the cause of the error
When you submit a transaction to a Midnight node, the JSON-RPC layer may reject it with code 1010:
{
"code": 1010,
"message": "Invalid Transaction",
"data": "Custom error: 155"
}
Code 1010 itself is a Substrate envelope, not a Midnight-specific error. It signals that the node's transaction pool rejected the extrinsic. The actionable signal is the N in Custom error: N, which is a u8 (0–255) corresponding to a LedgerApiError variant defined by the Midnight node.
The 1010 is inherited from Substrate. The inner u8 is Midnight's. To diagnose the problem, you must decode the u8.
Extract the inner u8
The inner u8 is embedded in the data field of the RPC error response. Use the steps below to extract it from common client environments.
Capture the full RPC response
Capture the complete error response, not just the message string. Many wallet libraries and CLI wrappers truncate the data field by default.
- JavaScript
- cURL
try {
await wallet.submitTransaction(tx);
} catch (err) {
console.error(String(err));
}
wallet is a WalletFacade and tx is the finalized transaction. String(err) prints the whole error chain, which ends with the node's response, for example RpcError: 1010: Invalid Transaction: Custom error: 155. err.message holds only the outer Transaction submission error, and JSON.stringify(err) drops the node's text. For the list of wrappers between your code and the node, see Transaction submission errors.
curl -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"author_submitExtrinsic","params":["0x..."]}' \
http://localhost:9944
Read the trailing integer in the data field
The data field ends with Custom error: N where N is the variant code:
"data": "Custom error: 155"
In this example, N is 155.
Look up the variant
Find the u8 in the error tables on the Node error codes page. The tables group the codes by range, and each row gives the variant name, a description, and a fix.
The Midnight node defines the variant numbering, which may change across releases. The error tables list the codes for node version 1.0.x. Always cross-reference the variant against the release notes for the node version your network is running.
Common causes and fixes
The following variants are common causes of 1010 errors.
168 FeeCalculation / 155 FeeCalculationError: fee calculation failed for the submitted transaction
The ledger can't calculate a fee in two cases:
- One cost dimension of the transaction is above its block limit.
- Validating the transaction and applying its guaranteed part would take longer than the ledger allows for a transaction of that size.
Split the work across smaller transactions. An underpaid fee doesn't cause these codes. The node rejects a transaction that pays less than its fee with 138 BalanceCheckOverspend.
154 BlockLimitExceededError: the transaction would exceed the block resource limits
Reduce the number of intents, calls, or similar in the transaction. For batched operations, split the work across multiple transactions.
108 ReplayCounterMismatch / 193 ReplayProtectionViolation: replay protection rejected the transaction
108 means that the counter in a contract maintenance update doesn't match the contract's current maintenance counter. Read the contract's current state and rebuild the update. 193 means that the ledger has already applied the same intent, so don't resubmit a transaction that might already be in a block. The node rejects a transaction that arrives after its TTL, or with a TTL too far in the future, with 182 TransactionApplicationError.
115 InvalidProof: a zero-knowledge proof failed verification
Confirm that the proof server is running a version compatible with the node and SDK. See run a proof server and the release compatibility matrix.
166 InvalidNetworkId: the transaction was constructed for a different network
Verify that the SDK and wallet are configured for the same network ID as the node you are submitting to. For example, a preprod node rejects a transaction built with the network ID preview.
126 Unbalanced / 138 BalanceCheckOverspend: the transaction's inputs and outputs do not balance
The wallet attempted to spend more than the available coin set permits, or change outputs were miscalculated. Re-sync the wallet and rebuild the transaction.
When 1010 has no inner u8
If the response contains code: 1010 but no Custom error: N substring, a Substrate check rejected the transaction rather than the Midnight ledger. Midnight transactions reach the node as the unsigned send_mn_transaction call, which the node checks in validate_unsigned. There is no signer, nonce, or mortal era to get wrong. The case you are likely to see is a transaction that is too heavy for one block:
1010: Invalid Transaction: Transaction would exhaust the block limits
Substrate's weight check returns this when the transaction passes the ledger's checks but needs more of a block than the node allows for a single transaction. The usual cause is a contract deploy with many exported circuits, because the deploy carries one verifier key per circuit. Deploy the contract with the circuits that fit, then add the remaining verifier keys with signed maintenance updates. The batched deploy runbook walks through this.
This rejection is not in the error tables because it never reaches the ledger.
Sometimes there is no 1010 at all, only TransactionInvalidError: Transaction is invalid and was rejected by the node. In that case the node accepted the transaction into its pool and then dropped it later, for example while building a block. See Submission error messages.
Verify the fix
After identifying and addressing the variant, resubmit the transaction and confirm that the node accepts it:
# Re-submit and observe the response
curl -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"author_submitExtrinsic","params":["0x..."]}' \
http://localhost:9944
A successful submission returns a transaction hash rather than an error envelope.
Get help
If you cannot identify the variant or the rejection persists after applying the fixes above:
- Confirm the node version: Variant numbering changes across releases. Check the node release notes for the version your network is running.
- Check the compatibility matrix: Verify the proof server, runtime, and SDK match the supported set in the release compatibility matrix.