For the complete documentation index, see llms.txt
Midnight node error codes
Midnight node errors are LedgerApiError codes mapped to u8 (0–255). They surface via Substrate's InvalidTransaction::Custom(u8) when the node rejects a transaction at the ledger level.
They often occur when the node rejects a submitted transaction with Custom(N) in the Substrate dispatch error.
A pallet-level DispatchError::Module surfaces with index 5 (pallet_midnight) or 6 (pallet_midnight_system) and you need to decode the inner error. To learn how to decode the inner error, see the Decode 1010 transaction rejection errors troubleshooting guide.
If your error came from a wallet or SDK call, such as SubmissionError: Transaction submission error, start with Transaction submission errors. That section shows how to find the node code inside the SDK error.
Error tables by code range
Below is a list of the Midnight node specific errors categorized by type and status code. The error tables group errors by code range to help you identify the error types.
Deserialization errors (0–11)
Errors that occur when the node fails to deserialize data from the wire format.
| Code | Name | Description | How to fix |
|---|---|---|---|
| 0 | NetworkId | Failed to deserialize the network ID | Check SDK version compatibility, verify network ID encoding |
| 1 | Transaction | Failed to deserialize transaction payload | Verify transaction was built with a compatible SDK version |
| 2 | LedgerState | Failed to deserialize ledger state | Internal node error |
| 3 | ContractAddress | Failed to deserialize contract address | Verify the contract address format |
| 4 | PublicKey | Failed to deserialize public key | Check key format and encoding |
| 5 | VersionedArenaKey | Failed to deserialize versioned arena key | Internal |
| 6 | UserAddress | Failed to deserialize user address | Verify address format |
| 7 | TypedArenaKey | Failed to deserialize typed arena key | Internal |
| 8 | SystemTransaction | Failed to deserialize system transaction | Governance/bridge transaction format error |
| 9 | DustPublicKey | Failed to deserialize DUST public key | Check DUST key format |
| 10 | CNightGeneratesDustActionType | Failed to deserialize cNIGHT-generates-DUST action type | Internal bridge/observation error |
| 11 | CNightGeneratesDustEvent | Failed to deserialize cNIGHT-generates-DUST event | Internal bridge/observation error |
Most deserialization errors occur due to version mismatch. Always refer to the compatibility matrix to ensure you are using compatible versions of Midnight blockchain components.
Serialization errors (50–63)
Errors that occur when the node fails to serialize data for storage or transmission.
| Code | Name | Description | How to fix |
|---|---|---|---|
| 50 | TransactionIdentifier | Failed to serialize transaction identifier | Internal |
| 51 | LedgerState | Failed to serialize ledger state | Internal node error |
| 52 | LedgerParameters | Failed to serialize ledger parameters | Internal node error |
| 53 | ContractAddress | Failed to serialize contract address | Internal |
| 54 | ContractState | Failed to serialize contract state | The contract state might be corrupt |
| 55 | ContractStateToJson | Failed to serialize contract state to JSON | Contract state format incompatible with JSON serialization |
| 56 | ZswapState | Failed to serialize Zswap state | Internal Zswap error |
| 57 | UnknownType | Failed to serialize an unknown type | Internal |
| 58 | MerkleTreeDigest | Failed to serialize Merkle tree digest | Internal Merkle tree error |
| 59 | VersionedArenaKey | Failed to serialize versioned arena key | Internal |
| 60 | TypedArenaKey | Failed to serialize typed arena key | Internal |
| 61 | CNightGeneratesDustEvent | Failed to serialize cNIGHT-generates-DUST event | Internal bridge error |
| 62 | SystemTransaction | Failed to serialize system transaction | Internal governance error |
| 63 | ArenaHash | Failed to serialize arena hash | Internal |
Transaction invalid (100–109, 193–200)
Errors that occur when the node applies a transaction to the ledger state and then rejects it for violating a ledger invariant.
| Code | Name | Description | How to fix |
|---|---|---|---|
| 100 | EffectsMismatch | Declared transaction effects don't match the computed effects | Rebuild the transaction. The effects declaration is stale or the SDK computed it incorrectly |
| 101 | ContractAlreadyDeployed | A contract already exists at the target address | Use a different contract address or find the existing deployment |
| 102 | ContractNotPresent | Called a contract that doesn't exist at the given address | Verify the contract address; deploy the contract first |
| 103 | Zswap | Zswap-level transaction error (e.g., double-spend, unknown Merkle root) | Check for nullifier reuse, verify coin tree root is current |
| 104 | Transcript | The node rejected on-chain transcript execution | Check contract logic; the circuit's on-chain transcript failed |
| 105 | InsufficientClaimable | Not enough NIGHT tokens to claim | Ensure sufficient NIGHT balance for the operation |
| 106 | VerifierKeyNotFound | Verifier key missing for the circuit operation | Deploy the verifier key before calling the circuit |
| 107 | VerifierKeyAlreadyPresent | Verifier key already exists for this operation | The key is already deployed; no action needed |
| 108 | ReplayCounterMismatch | Signed counter doesn't match (replay attack prevention) | Rebuild the transaction with the current replay counter |
| 109 | UnknownError | Unclassified transaction invalid error | Check node logs for details |
| 193 | ReplayProtectionViolation | Transaction violates replay protection (duplicate intent) | This transaction or intent was already submitted |
| 194 | BalanceCheckOutOfBounds | Token balance would overflow or underflow | Verify token amounts don't exceed representable range |
| 195 | InputNotInUtxos | Input references a UTXO that doesn't exist in the set | The coin may already be spent; resync wallet state |
| 196 | DustDoubleSpend | Attempt to spend the same DUST twice | DUST UTXO already consumed; resync DUST wallet |
| 197 | DustDeregistrationNotRegistered | Attempting to deregister a DUST address that isn't registered | Verify the DUST address is currently registered |
| 198 | GenerationInfoAlreadyPresent | DUST generation info already exists | Duplicate generation info submission |
| 199 | InvariantViolation | Protocol-level invariant violated (e.g., NIGHT supply exceeded) | Transaction would break fundamental protocol rules |
| 200 | RewardTooSmall | Claimed reward is below the minimum payout threshold | Accumulate more rewards before claiming |
Transaction malformed (110–139, 166–192)
Errors that occur when the node rejects a transaction that is structurally invalid.
| Code | Name | Description | How to fix |
|---|---|---|---|
| 110 | VerifierKeyNotSet | Contract deployed without required verifier key | Include verifier keys when deploying the contract |
| 111 | TransactionTooLarge | Transaction exceeds maximum allowed size | Reduce transaction payload; split into multiple transactions |
| 112 | VerifierKeyTooLarge | Verifier key exceeds deserialization limit | Use a smaller circuit or contact Midnight support |
| 113 | VerifierKeyNotPresent | Referenced verifier key not found | Deploy the contract with the verifier key before calling the circuit |
| 114 | ContractNotPresent | Transaction references a non-existent contract | Verify contract address; deploy the contract first |
| 115 | InvalidProof | Zero-knowledge proof verification failed | Regenerate the proof. Ensure the proof server is compatible |
| 116 | BindingCommitmentOpeningInvalid | Binding commitment was incorrectly opened | Internal Zswap error — rebuild the transaction |
| 117 | NotNormalized | Transaction is not in normal form | Rebuild with the SDK; normalize the transaction before submission |
| 118 | FallibleWithoutCheckpoint | Fallible transcript missing initial checkpoint | Add kernel.checkpoint() at the start of fallible sections |
| 119 | ClaimReceiveFailed | Failed to claim a coin commitment receive | Coin commitment format error; rebuild the transaction |
| 120 | ClaimSpendFailed | Failed to claim a coin commitment spend | Coin commitment format error; rebuild the transaction |
| 121 | ClaimNullifierFailed | Failed to claim a nullifier | Nullifier format error; rebuild the transaction |
| 122 | ClaimCallFailed | Failed to claim a contract call | Contract call format error; rebuild the transaction |
| 123 | InvalidSchnorrProof | Fiat-Shamir Schnorr proof verification failed | Signing error — regenerate the transaction signature |
| 124 | UnclaimedCoinCom | Contract-owned output left unclaimed | Ensure you claim all contract outputs in the transaction before submitting the transaction |
| 125 | UnclaimedNullifier | Contract-owned coin input left unauthorized | You must authorize all contract inputs |
| 126 | Unbalanced | Negative balance in a token type | Transaction doesn't balance. Check token amounts |
| 127 | Zswap | Zswap offer is structurally malformed | Rebuild the Zswap offer and check proof validity |
| 128 | BuiltinDecode | FAB (field-aligned binary) decode error | Internal encoding error. Verify data formats |
| 129 | GuaranteedLimit | Exceeded guaranteed section limits | Reduce the guaranteed section size |
| 130 | MergingContracts | Error merging contract intents | These contracts cannot merge; check configuration |
| 131 | CantMergeTypes | Attempted to merge incompatible transaction types | Transaction types must be compatible for merging |
| 132 | ClaimOverflow | Claimed coin value overflows deltas | Token amounts exceed representable range |
| 133 | ClaimCoinMismatch | ClaimRewards coin doesn't match the real coin | Rebuild the claim with correct coin data |
| 134 | KeyNotInCommittee | Signing key is not a committee member | Only committee members can sign this operation |
| 135 | InvalidCommitteeSignature | Committee signature verification failed | Verify the signing key and signature |
| 136 | ThresholdMissed | Committee approval threshold not met | Gather more committee signatures |
| 137 | TooManyZswapEntries | Too many Zswap entries (>=2^16) | Reduce the number of shielded operations |
| 138 | BalanceCheckOverspend | Negative balance in a transaction segment | Segment spends more than available; check amounts |
| 139 | UnknownError | Unclassified malformed transaction error | Check node logs for details |
| 166 | InvalidNetworkId | Transaction's network ID doesn't match the node's network | Verify networkId matches the target (for example, undeployed for devnet); check setNetworkId() |
| 167 | IllegallyDeclaredGuaranteed | Guaranteed segment (0) used where forbidden | Don't use segment_id 0 for intents |
| 168 | FeeCalculation | Fee calculation error | Transaction size or timing parameters are invalid |
| 169 | InvalidDustRegistrationSignature | DUST registration signature verification failed | Regenerate DUST registration with correct keys |
| 170 | InvalidDustSpendProof | DUST spend proof verification failed | Regenerate DUST spend proof |
| 171 | OutOfDustValidityWindow | DUST outside its validity time window | DUST creation time is outside the allowed window; use fresher DUST |
| 172 | MultipleDustRegistrationsForKey | Multiple DUST registrations for same key in one intent | Only one DUST registration per key per intent |
| 173 | InsufficientDustForRegistrationFee | Not enough DUST to pay registration fee | Acquire more DUST before registering |
| 174 | MalformedContractDeploy | Contract deployment is structurally invalid | Check for non-zero balance or incorrect charged state in deploy |
| 175 | IntentSignatureVerificationFailure | Intent signature verification failed | Regenerate intent signatures |
| 176 | IntentSignatureKeyMismatch | Signing key doesn't match verifying key | Use the correct signing key for the intent |
| 177 | IntentSegmentIdCollision | Duplicate segment_id in intent merge | Each intent must have a unique segment_id |
| 178 | IntentAtGuaranteedSegmentId | Intent placed at segment_id 0 (reserved for guaranteed) | Use segment_id >= 1 for intents |
| 179 | UnsupportedProofVersion | Proof version not supported | Update SDK/proof server to a compatible version |
| 180 | GuaranteedTranscriptVersion | Guaranteed transcript version not supported | Update to a compatible ledger/SDK version |
| 181 | FallibleTranscriptVersion | Fallible transcript version not supported | Update to a compatible ledger/SDK version |
| 182 | TransactionApplicationError | Intent TTL expired, too far in future, or duplicate | Check intent timing; avoid resubmitting same intent |
| 183 | BalanceCheckOutOfBounds | Balance overflow/underflow in a segment | Token amounts in a segment exceed representable range |
| 184 | BalanceCheckConversionFailure | Failed to convert balance to i128 | Token amount too large for internal representation |
| 185 | PedersenCheckFailure | Binding commitment mismatch | Internal cryptographic error — rebuild the transaction |
| 186 | EffectsCheckFailure | Transaction effects validation failed | Declared effects don't match computed effects |
| 187 | DisjointCheckFailure | Input/output sets are not disjoint | Shielded and transient inputs/outputs must not overlap |
| 188 | SequencingCheckFailure | Call graph sequencing violated | Contract calls must respect ordering constraints |
| 189 | InputsNotSorted | Unshielded inputs are not sorted | Sort unshielded inputs before submission |
| 190 | OutputsNotSorted | Unshielded outputs are not sorted | Sort unshielded outputs before submission |
| 191 | DuplicateInputs | Duplicate unshielded inputs | Remove duplicate inputs from the transaction |
| 192 | InputsSignaturesLengthMismatch | Input count doesn't match signature count | Ensure each input has a corresponding signature |
Infrastructure errors (150–155, 165)
Errors that occur when the node encounters infrastructure errors not directly related to transaction content.
| Code | Name | Description | How to fix |
|---|---|---|---|
| 150 | LedgerCacheError | Ledger cache mutex/lock poisoned | Restart the node; this is an internal concurrency error |
| 151 | NoLedgerState | No ledger state present in the node | Node may not be fully synced; wait for sync to complete |
| 152 | LedgerStateScaleDecodingError | SCALE decoding of ledger state failed | The node state might be corrupt; try a resync |
| 153 | ContractCallCostError | Failed to calculate contract call cost | Internal cost model error |
| 154 | BlockLimitExceededError | Transaction exceeds block limits | Reduce transaction size or wait for a less congested block |
| 155 | FeeCalculationError | Fee calculation failed | Internal fee model error |
| 165 | GetTransactionContextError | Failed to retrieve transaction context | Internal node error |
System transaction errors (201–210)
Errors that occur when the node encounters errors from governance and bridge system transactions. These are special transactions submitted by the network's governance mechanisms.
| Code | Name | Description | How to fix |
|---|---|---|---|
| 201 | IllegalPayout | Payout exceeds remaining supply or bridge pool | Payout amount is too large for available funds |
| 202 | InsufficientTreasuryFunds | Treasury doesn't have enough funds | Requested amount exceeds treasury balance |
| 203 | CommitmentAlreadyPresent | Faerie-gold double-commitment attempt | Commitment already exists in the tree |
| 204 | UnknownError | Unclassified system transaction error | Check node logs |
| 205 | ReplayProtectionFailure | System transaction replay protection violated | Duplicate system transaction |
| 206 | IllegalReserveDistribution | Reserve distribution exceeds supply | Distribution amount exceeds available reserves |
| 207 | GenerationInfoAlreadyPresent | DUST generation info already inserted | Duplicate generation info |
| 208 | InvalidBasisPoints | Bridge fee basis points >= 10,000 | Basis points must be between 0 and 9,999 |
| 209 | InvariantViolation | Protocol-level invariant violated | Transaction would break fundamental protocol rules |
| 210 | TreasuryDisabled | Attempted to access disabled treasury | Treasury feature is not enabled |
Host API error (255)
Errors that occur when the node encounters errors from the host API.
| Code | Name | Description | How to fix |
|---|---|---|---|
| 255 | HostApiError | Error in host API processing | Internal runtime error; check node logs |
Pallet dispatch errors
When a transaction fails inside a Substrate pallet, the error surfaces as DispatchError::Module { index, error }.
The index identifies the pallet and error is the SCALE-encoded variant index within that pallet's error enum.
Below is a list of the Midnight node specific pallet errors categorized by pallet and variant.
Pallet index map
Below is a list of the Midnight node specific pallet indices and their descriptions.
| Index | Pallet | Description |
|---|---|---|
| 5 | pallet_midnight | Core Midnight ledger pallet |
| 6 | pallet_midnight_system | System transaction pallet |
| 13 | pallet_cnight_observation | cNIGHT bridge observation |
| 44 | pallet_federated_authority | Governance authority |
| 45 | pallet_federated_authority_observation | Authority observation |
| 50 | pallet_system_parameters | System parameters |
| 51 | pallet_throttle | Transaction throttling |
pallet_midnight
Errors from the core pallet managing the ledger state and transactions.
| Variant | Name | Description |
|---|---|---|
| 0 | NewStateOutOfBounds | New ledger state is out of acceptable bounds |
| 1 | Deserialization | Wraps DeserializationError (codes 0–11) |
| 2 | Serialization | Wraps SerializationError (codes 50–63) |
| 3 | Transaction | Wraps TransactionError (codes 100–210) |
| 4 | LedgerCacheError | Ledger cache poisoned (code 150) |
| 5 | NoLedgerState | No ledger state (code 151) |
| 6 | LedgerStateScaleDecodingError | SCALE decode failure (code 152) |
| 7 | ContractCallCostError | Cost calculation failure (code 153) |
| 8 | BlockLimitExceededError | Block limit exceeded (code 154) |
| 9 | FeeCalculationError | Fee calculation failure (code 155) |
| 10 | HostApiError | Host API error (code 255) |
| 11 | NetworkIdNotString | Network ID not a valid string |
| 12 | GetTransactionContextError | Transaction context retrieval error (code 165) |
pallet_midnight_system
Errors from the system transaction pallet.
| Variant | Name | Description |
|---|---|---|
| 0 | LedgerApiError | Wraps full LedgerApiError |
| 1 | SystemTransactionNotAllowedForGovernance | Governance-disallowed system transaction |
pallet_federated_authority
Errors from the multi-collective governance authority pallet.
| Variant | Name | Description |
|---|---|---|
| 0 | MotionAlreadyApproved | Authority already approved this motion |
| 1 | MotionApprovalMissing | Approver not in the approval list |
| 2 | MotionApprovalExceedsBounds | Exceeds maximum authority bodies |
| 3 | MotionNotFound | Motion does not exist |
| 4 | MotionNotEnded | Motion voting not yet complete |
| 5 | MotionHasEnded | Motion ended; no more changes allowed |
| 6 | MotionTooEarlyToClose | Approval period hasn't ended yet |
| 7 | MotionAlreadyExists | Motion already exists |
| 8 | MotionExpired | Motion expired without enough approvals |
| 9 | MotionWeightBoundTooLow | Weight bound too low for the call |
pallet_cnight_observation
Errors from the cNIGHT bridge integration pallet.
| Variant | Name | Description |
|---|---|---|
| 0 | MaxCardanoAddrLengthExceeded | Cardano wallet address too long |
| 1 | MaxRegistrationsExceeded | Too many registrations |
| 2 | LedgerApiError | Wraps LedgerApiError |
| 3 | InherentAlreadyExecuted | Only one inherent call per block |
| 4 | CardanoPositionRegression | Next Cardano position doesn't advance |
| 5 | TooManyUtxos | UTXO count exceeds capacity |
pallet_federated_authority_observation
Errors from the multi-collective governance synchronization pallet.
| Variant | Name | Description |
|---|---|---|
| 0 | EmptyMembers | Membership set is empty |
| 1 | DuplicatedMembers | Duplicate members in the set |
| 2 | InherentAlreadyExecuted | Only one inherent call per block |
pallet_system_parameters
Errors from the system parameters pallet.
| Variant | Name | Description |
|---|---|---|
| 0 | UrlTooLong | URL exceeds maximum allowed length |
JSON-RPC error codes
The Midnight node uses standard JSON-RPC 2.0 error codes from the jsonrpsee crate. These are the most common error codes you might encounter when interacting with the node.
| Code | Name | Used in | Description |
|---|---|---|---|
| -32602 | INVALID_PARAMS | State RPC, Block RPC, Events, Peer Info | Bad contract address, account address, block hash, peer ID, or other invalid parameter |
| -32603 | INTERNAL_ERROR | Peer Info RPC, System Parameters RPC | Failed to send/receive internal requests, runtime API failures |
Transaction submission errors
When a DApp or wallet submits a transaction, the node's error passes through several software layers before it reaches your code. Each layer wraps the error from the layer below and adds its own message. The message you see first is usually the outermost wrapper, not the cause.
How the error layers fit together
The node validates each submitted transaction against the ledger. If validation fails, the node converts the ledger error to one of the u8 codes in the error tables. The Substrate transaction pool then returns that code in JSON-RPC error 1010:
{ "code": 1010, "message": "Invalid Transaction", "data": "Custom error: 196" }
When you submit through the Midnight wallet SDK, the SDK layers wrap the error in this order:
- The Polkadot.js API client turns the response into an
RpcErrorwith the message1010: Invalid Transaction: Custom error: 196. - The wallet SDK node client (
@midnight-ntwrk/wallet-sdk-node-client) wraps theRpcErrorin aSubmissionErrorwith the messageTransaction submission failed. - The wallet SDK submission service (
@midnight-ntwrk/wallet-sdk-capabilities) wraps that error in anotherSubmissionErrorwith the messageTransaction submission error. - The promise-based API rejects with an Effect
FiberFailurewhose name is(FiberFailure) SubmissionError.WalletFacade.submitTransactionreverts the transaction in the wallet's shielded, unshielded, and DUST state, then rethrows this error. - Midnight.js
submitCallTxwraps the error in a plainErrorwhose message starts withUnexpected error submitting scoped transactionand includes the text of the wrapped error.
The message property of a FiberFailure holds only the outermost text, and FiberFailure doesn't set error.cause. To see the full chain, including Custom error: N, convert the error to a string with String(error), or log it with console.error(error) in Node.js. Browser consoles show only the outer message, so use String(error) there. JSON.stringify(error) drops the node error text.
If you run the node yourself, the node log also records the reason in a line that contains Rejected transaction <hash> from mempool.
If your DApp submits through a browser wallet with the DApp Connector API, the wallet performs the submission and returns an error with code and reason fields. The API doesn't require the wallet to include the node's response. If the reason text includes Custom error: N, look up N in the error tables.
Node ledger codes are u8 values, so they're always between 0 and 255. If you see a larger number, such as a five-digit code, it didn't come from the node error tables on this page. Look for the 1010 response or the Custom error: N text elsewhere in the error chain, or check the node log.
Submission error messages
The following table lists the messages you might see when a submission fails, the layer that produces each one, and what to do next.
| Message or error | Origin | Description | How to fix |
|---|---|---|---|
1010: Invalid Transaction: Custom error: N | Node (Substrate transaction pool) | The node's ledger rejected the transaction with code N | Look up N in the error tables |
1010: Invalid Transaction without Custom error: N | Node (Substrate transaction pool) | A Substrate check rejected the transaction before the ledger checked it | See When 1010 has no inner u8 |
SubmissionError: Transaction submission failed | Wallet SDK node client | The call that sends the transaction to the node failed. The node's response is in cause | Read cause for the 1010 response |
SubmissionError: Transaction submission error | Wallet SDK submission service | Any node client error during submission, including a node rejection, a lost connection, or a transaction the node reported as dropped or invalid | Print the full error chain and find the innermost error |
(FiberFailure) SubmissionError | Wallet SDK (Effect runtime) | The promise-based wallet SDK API rejected with the SubmissionError described in the previous row | Use String(error) to print the full cause chain |
Unexpected error submitting scoped transaction '<name>': ... | Midnight.js | submitCallTx failed before the transaction reached a block. The message includes the text of the underlying error | Find Custom error: N in the message and look up N |
CallTxFailedError | Midnight.js | The transaction reached a block, but its status isn't SucceedEntirely | Check finalizedTxData.status on the error to see which part of the transaction failed |
Failed to decode ledger event payload | Wallet SDK shielded wallet | During sync, the wallet couldn't deserialize a ledger event it received from the indexer. One possible cause is a mismatch between the ledger version bundled with the wallet SDK and the ledger version the network runs. The same message appears if the indexer returns any payload the wallet can't decode | Use wallet SDK and Midnight.js versions from the compatibility matrix for your network |
Common submission codes
The following node codes often appear inside submission errors. The meanings apply to node version 1.0.x.
| Code | Name | Description | How to fix |
|---|---|---|---|
| 103 | Zswap | The shielded (Zswap) part of the transaction conflicts with ledger state. The node reports this when a coin's nullifier is already spent, a new coin commitment already exists, the proof refers to a coin tree root the node doesn't recognize, or a Merkle tree update fails. The node keeps past coin tree roots for about one hour, so the node rejects a transaction whose proof uses a root older than that | Let the wallet finish syncing, then rebuild and resubmit the transaction. Don't submit several transactions that spend the same shielded coins at the same time |
| 196 | DustDoubleSpend | The DUST UTXO that pays the transaction fee has already been spent. Its nullifier is already in the ledger's DUST nullifier set | Let the wallet sync the earlier transaction, then rebuild and resubmit. Don't run more than one wallet instance from the same seed at the same time, and don't resubmit a transaction that might already be in a block |