For the complete documentation index, see llms.txt
Ledger error reference
The midnight-ledger crate defines the full taxonomy of transaction validation, execution, and state management errors. These are the Rust-level error types behind the numeric LedgerApiError codes that the node surfaces.
Error hierarchy
Understanding the chain from top-level to low-level is essential when reading nested error output. A MalformedTransaction::InvalidProof near the top of a chain might trace back to a deep OnchainProgramError::Decode inside a contract transcript execution.
MalformedTransaction
└─ wraps zswap::MalformedOffer
└─ wraps TranscriptRejected
└─ wraps OnchainProgramError
└─ wraps InvalidBuiltinDecode
└─ wraps merkle_tree::InvalidUpdate
Error types
The following sections describe each error type in the chain, from the top-level transaction envelope down to low-level tree and VM operations.
MalformedTransaction
Over 50 variants, parameterized as MalformedTransaction<D>. These are structural validity errors the ledger checks before any state application. The ledger rejects malformed transactions without modifying state.
Proof and cryptographic errors
These errors indicate failures in zero-knowledge proof verification or cryptographic consistency checks.
| Variant | Description | Fix |
|---|---|---|
BindingCommitmentOpeningInvalid | The binding commitment opening does not match the committed value. | Indicates a bug in transaction construction; recheck commitment generation. |
InvalidNetworkId | The transaction targets a different network (for example, Mainnet vs. Devnet). | Rebuild the transaction targeting the correct network ID. |
InvalidProof | A zero-knowledge proof failed verification. | Reproving required; check that the witness and public inputs match. |
InvalidSchnorrProof | A Schnorr signature proof failed verification. | Key mismatch or corrupted signing data; re-sign. |
PedersenCheckFailure | A Pedersen commitment consistency check failed. | Balance or value encoding error; recheck transaction values. |
Structural errors
These errors indicate violations of canonical form or transaction structure rules.
| Variant | Description | Fix |
|---|---|---|
FallibleWithoutCheckpoint | A fallible transaction segment lacks the required checkpoint. | Add a checkpoint to the fallible segment. |
NotNormalized | Transaction fields are not in the required canonical sort order. | Sort and normalize transaction fields per the ledger spec before submitting. |
TooManyZswapEntries | The transaction contains more Zswap entries than the protocol allows. | Split Zswap operations across multiple transactions. |
TransactionTooLarge | The serialized transaction exceeds the maximum allowed byte size. | Split into smaller transactions or reduce payload size. |
VerifierKeyTooLarge | A verifier key in the transaction exceeds the size limit. | Check that the correct (non-debug) verifier key is in use. |
Claims errors
These errors occur when coin claim data is inconsistent or fails verification.
| Variant | Description | Fix |
|---|---|---|
ClaimCoinMismatch | The coin referenced in a claim does not match the expected coin. | Ensure the claim targets the correct coin data. |
ClaimNullifierFailed | The nullifier in a claim is invalid or does not match. | Regenerate the nullifier from the correct key and coin data. |
ClaimOverflow | Arithmetic overflow occurred while summing claim values. | Reduce individual claim values; the total may exceed u64::MAX. |
ClaimReceiveFailed | A coin receive claim is invalid or the ledger cannot verify it. | Check that the claim data matches the target coin. |
ClaimSpendFailed | A coin spend claim failed verification. | Verify the spend authorization and nullifier data. |
UnclaimedCoinCom | A coin commitment is present but has no corresponding claim. | Ensure every coin commitment has a valid associated claim. |
UnclaimedNullifier | A nullifier is present but has no corresponding coin claim. | Ensure every nullifier has a corresponding spend claim. |
Unbalanced | The transaction inputs and outputs do not balance; value is not conserved. | Recheck token amounts across all inputs and outputs. |
Committee errors
These errors arise when a transaction's committee signatures are missing, insufficient, or invalid.
| Variant | Description | Fix |
|---|---|---|
InvalidCommitteeSignature | A committee signature has an invalid format or does not verify. | Re-collect signatures from valid committee members. |
KeyNotInCommittee | A key used for signing is not a member of the expected committee. | Use a key registered as a committee member for this epoch. |
ThresholdMissed | The required threshold of committee signatures was not reached. | Gather signatures from more committee members before submitting. |
Intents errors
These errors occur when transaction intents carry invalid signatures or conflicting segment identifiers.
| Variant | Description | Fix |
|---|---|---|
IntentAtGuaranteedSegmentId | An intent targets a guaranteed segment ID, which is not permitted. | Move the intent to a non-guaranteed segment. |
IntentSegmentIdCollision | Two intents reference the same segment ID. | Assign unique segment IDs to each intent. |
IntentSignatureVerificationFailure | An intent's signature failed verification. | Re-sign the intent with the correct key. |
IntentSignatureKeyMismatch | The signing key does not match the key declared in the intent. | Ensure the intent uses the key it references. |
Balance check errors
These errors occur when token balance verification fails during transaction validation.
| Variant | Description | Fix |
|---|---|---|
BalanceCheckConversionFailure | Type conversion failed during balance verification. | Indicates a bug in value encoding; check token type consistency. |
BalanceCheckOutOfBounds | A balance value is outside the valid numeric range for the check. | Verify that all token amounts are within protocol-defined bounds. |
BalanceCheckOverspend | The transaction attempts to spend more than is available. | Reduce spend amounts or add sufficient inputs. |
DUST errors
These errors occur when DUST registration or spend operations fail validation.
| Variant | Description | Fix |
|---|---|---|
InsufficientDustForRegistrationFee | The DUST amount is below the minimum required to cover the registration fee. | Increase the DUST amount to meet the minimum fee threshold. |
InvalidDustRegistrationSignature | The DUST registration signature is invalid. | Re-sign the DUST registration with the correct key. |
InvalidDustSpendProof | The proof for a DUST spend is invalid. | Regenerate the spend proof with correct witness data. |
MultipleDustRegistrationsForKey | The same key appears in multiple DUST registrations in one transaction. | Use each DUST key at most once per transaction. |
OutOfDustValidityWindow | The DUST registration or spend is outside the allowed validity window. | Check block height and resubmit within the validity window. |
Version errors
These errors occur when a proof or transcript uses a version the node does not recognize.
| Variant | Description | Fix |
|---|---|---|
FallibleTranscriptVersion | The transcript version is invalid for a fallible segment. | Ensure fallible segments use the correct transcript version format. |
GuaranteedTranscriptVersion | The transcript version is invalid for a guaranteed segment. | Ensure guaranteed segments use the correct transcript version format. |
UnsupportedProofVersion | The proof uses a version the node does not support. | Upgrade the SDK or reproduce the proof with a supported version. |
Check errors
These errors occur when static consistency checks on transaction effects or segment ordering fail.
| Variant | Description | Fix |
|---|---|---|
DisjointCheckFailure | Segments that should be disjoint share resources or state. | Ensure segments operate on non-overlapping state. |
EffectsCheckFailure | The declared effects of the transaction failed static consistency checks. | Verify that declared effects match what contract execution would produce. |
SequencingCheckFailure | The transaction violated segment ordering constraints. | Reorder segments to satisfy sequencing requirements. |
Sorting and deduplication errors
These errors occur when transaction inputs or outputs violate canonical ordering or uniqueness requirements.
| Variant | Description | Fix |
|---|---|---|
DuplicateInputs | The same input appears more than once in the transaction. | Remove duplicate inputs. |
InputsNotSorted | Transaction inputs are not in the required canonical sort order. | Sort inputs according to the ledger's canonical ordering before building the transaction. |
InputsSignaturesLengthMismatch | The number of input signatures does not match the number of inputs. | Provide exactly one signature per input. |
OutputsNotSorted | Transaction outputs are not in the required canonical sort order. | Sort outputs canonically before building the transaction. |
TransactionInvalid
These state-application errors occur when the ledger applies a structurally valid transaction to the current state but rejects it due to state inconsistencies. This enum is #[non_exhaustive] and defines 19 variants.
| Variant | Description | Fix |
|---|---|---|
BalanceCheckOutOfBounds | A balance value is out of valid range during state application. | Verify token amounts are within bounds after accounting for current state. |
ContractAlreadyDeployed | A contract deployment targets an address that already has a contract. | Deploy to a different address or verify deployment uniqueness. |
ContractNotPresent | A transaction calls a contract that does not exist at the given address. | Verify the contract address and confirm the contract exists at that address. |
DivideByZero | A division by zero occurred during transaction processing. | Indicates a bug in transaction value computation. |
DustDeregistrationNotRegistered | The transaction attempts to deregister a DUST key that has no active registration. | Confirm the key has an active registration before deregistering it. |
DustDoubleSpend | A DUST coin the transaction attempts to spend is already spent. | Check current DUST UTXO state; the coin has already been spent. |
EffectsMismatch | The actual effects of applying the transaction differ from the declared effects. | Declared effects must exactly match what contract execution produces. |
GenerationInfoAlreadyPresent | Generation info for this epoch/key is already recorded on-chain. | You can only submit generation info once per epoch. |
InputNotInUtxos | A transaction input references a UTXO that does not exist in the current state. | The UTXO may already be spent; fetch fresh state before building the transaction. |
InsufficientClaimable | The transaction attempts to claim more than is available in the claimable pool. | Reduce the claim amount or wait for more claimable funds to become available. |
InvariantViolation | The ledger detected an internal invariant violation. | Report as a bug; this should not occur with a correctly implemented node or SDK. |
MerkleTreeError | A Merkle tree operation failed during state application. | For more details, see the merkle_tree::InvalidUpdate section. |
ReplayCounterMismatch | The replay protection counter does not match the expected value. | Fetch the current replay counter from the node and use it in the transaction. |
ReplayProtectionViolation | The transaction violates replay protection constraints. | Ensure the transaction is not a duplicate or out-of-sequence. |
RewardTooSmall | The reward amount is below the minimum required. | Increase the reward amount to meet the protocol minimum. |
Transcript | The ledger rejected a contract transcript execution (wraps TranscriptRejected). | For more details, see the TranscriptRejected errors section. |
VerifierKeyAlreadyPresent | A verifier key registration targets a key that is already registered. | Do not re-register existing verifier keys. |
VerifierKeyNotFound | A verifier key referenced in the transaction is not registered on-chain. | Register the verifier key before submitting transactions that reference it. |
Zswap | A Zswap sub-operation failed (wraps zswap::TransactionInvalid). | For more details, see the Zswap errors section. |
OnchainProgramError
These errors surface when contract transcript execution fails inside the Impact VM on-chain execution engine. This enum defines 17 variants.
| Variant | Description |
|---|---|
ArithmeticOverflow | An arithmetic operation overflowed the supported integer range. |
AttemptedArrayDelete | An attempt made to delete an array element, which is not supported. |
BoundsExceeded | An array or buffer access targeted an out-of-bounds position. |
CacheMiss | A cache lookup for a required value returned no result during execution. |
CellBoundExceeded | A cell value exceeded the maximum allowed size. |
Decode | Failed to decode a value from the stack or program data (wraps InvalidBuiltinDecode). |
ExpectedCell | The VM expected a cell value at a stack position but found a different type. |
InvalidArgs | A built-in function received invalid or wrong-count arguments. |
LogBoundExceeded | A logging operation exceeded the maximum allowed log size. |
MerkleTreeError | A Merkle tree built-in operation failed inside the VM. |
MissingKey | A required key was not found in the contract state map. |
OutOfGas | The transaction ran out of gas during contract execution. |
RanOffStack | The VM stack ran out of space; a pop or read targeted an empty stack. |
RanPastProgramEnd | The program counter advanced past the end of the bytecode. |
ReadMismatch | A read from contract state returned a value that does not match the value declared in the transcript. |
StackOverflow | The VM call stack grew too deep, exceeding the recursion limit. |
TooLongForEqual | An equality comparison targeted values exceeding the maximum comparable length. |
TypeError(String) | A type mismatch occurred during VM execution. The string describes the mismatch. |
TranscriptRejected
This type wraps OnchainProgramError and represents failures during on-chain contract execution. It defines five variants.
| Variant | Description |
|---|---|
Decode | Failed to decode the transcript input before execution could begin. |
EffectDecodeError | Failed to decode the effects emitted by the contract execution. |
Execution | Contract execution failed (wraps OnchainProgramError). The inner error contains the VM-level failure. |
FinalStackWrongLength | After execution completed, the stack did not have the expected number of elements. |
WeakStateReturned | The contract returned a weakened state when the protocol required a full state. |
Zswap errors
Zswap manages private coin operations including shielded transfers, coin commitments, and double-spend prevention.
zswap::TransactionInvalid
State-level Zswap failures that occur when the ledger applies a Zswap operation to the current state.
| Variant | Description | Fix |
|---|---|---|
CommitmentAlreadyPresent | A coin commitment already exists in the commitment tree. | Duplicate commitment; check for replay or construction error. |
MerkleTreeError | A Merkle tree update failed during Zswap state application. | For more details, see the merkle_tree::InvalidUpdate section. |
NullifierAlreadyPresent | The nullifier has already been spent; this is a double-spend attempt. | The coin has been spent; do not attempt to spend it again. |
UnknownMerkleRoot | The Merkle root referenced in the proof is not known to the current state. | Fetch the current Merkle root from the node and rebuild the proof. |
zswap::MalformedOffer
Structural Zswap errors checked before any state application.
| Variant | Description | Fix |
|---|---|---|
ContractSentCiphertext | A contract attempted to send ciphertext, which is not permitted in this context. | Contracts must not produce ciphertext outputs directly. |
InvalidProof | A Zswap zero-knowledge proof failed verification. | Regenerate the proof with correct witness and public inputs. |
NonDisjointCoinMerge | A coin merge targeted non-disjoint coin sets. | Ensure merged coin sets are fully disjoint. |
NotNormalized | The offer is not in canonical normalized form. | Normalize the offer before including it in a transaction. |
zswap::OfferCreationFailed
Client-side errors encountered while constructing a Zswap offer.
| Variant | Description | Fix |
|---|---|---|
InvalidIndex | The offer construction used an invalid index. | Verify the coin index is within the valid range for the Merkle tree. |
MerkleTreeError | A Merkle tree operation failed during offer construction. | For more details, see the merkle_tree::InvalidUpdate section. |
NotContractOwned | The offer references a coin that is not owned by the expected contract. | Ensure you construct offers only for coins the correct contract owns. |
Proving | The zero-knowledge proving step failed during offer creation. | Check that all witnesses are valid; re-run proving with correct inputs. |
TreeNotRehashed | The Merkle tree requires a rehash after recent updates. | Call the tree rehash operation before constructing the offer. |
Merkle tree errors
These errors surface when operations on the commitment Merkle tree fail.
merkle_tree::InvalidIndex
Returned when a provided index is out of range for the current tree size.
| Variant | Description |
|---|---|
InvalidIndex(u64) | The provided index is out of range for the current Merkle tree size. |
merkle_tree::InvalidUpdate
Six variants representing structural failures when updating the Merkle tree.
| Variant | Description |
|---|---|
BadUpdatePath | The Merkle path provided for the update is incorrect or inconsistent. |
CollapsedIndex | An update targeted a collapsed (pruned) subtree node. |
EndBeforeStart | The end index of an update range is before the start index. |
EndOutOfTree | The end index of an update range extends past the tree boundary. |
NotFullyRehashed | The tree has pending updates without a rehash; it is in an inconsistent state. |
StubUpdate | An update targeted a stub node that cannot accept updates. |
WrongNumberOfSegments | The update provides a different number of segments than expected. |
Other error types
The following types cover client-side construction, fee calculation, system transactions, and auxiliary operations.
FeeCalculationError
Errors that occur during fee computation before transaction submission.
| Variant | Description |
|---|---|
BlockLimitExceeded | The transaction exceeded the block limit during fee computation. |
OutsideTimeToDismiss | The transaction exceeds the maximum allowed time-to-dismiss for its byte size. |
MalformedContractDeploy
Errors specific to contract deployment transactions, checked before state application.
| Variant | Description |
|---|---|
IncorrectChargedState | The contract deployment contains an incorrectly computed map of charged keys. |
NonZeroBalance | The contract deployment carries a non-zero token balance. Contract deployments must not include pre-existing balances. |
SystemTransactionError
These errors arise in protocol-level system transactions, such as epoch transitions and committee updates. This type defines 10 variants.
| Variant | Description |
|---|---|
CommitmentAlreadyPresent | A coin commitment already exists in the tree; this is a double-spend attempt. |
GenerationInfoAlreadyPresent | DUST generation info for this epoch already exists; the ledger rejects the duplicate insertion. |
IllegalPayout | The payout or bridge amount exceeds the remaining native token supply or bridge pool. |
IllegalReserveDistribution | The distribution amount exceeds the remaining reserve token supply. |
InsufficientTreasuryFunds | The treasury does not hold enough tokens of the requested type to fulfil the request. |
InvalidBasisPoints | The cardano_to_midnight_bridge_fee_basis_points value is 10,000 or greater, which is outside the valid range. |
InvariantViolation | The total NIGHT supply implied by the transaction exceeds MAX_SUPPLY. |
MerkleTreeError | A Merkle tree operation failed during the system transaction. See merkle_tree::InvalidUpdate for details. |
ReplayProtectionFailure | The system transaction violated replay protection constraints (wraps TransactionApplicationError). |
TreasuryDisabled | Governance has not yet enabled the treasury; the ledger rejects treasury access until stakeholders reach an agreement. |
TransactionConstructionError
Client-side errors encountered while building a transaction before submission.
| Variant | Description |
|---|---|
MissingVerifierKey | The contract operation lacks a verifier key; the proving step cannot proceed. |
ProofFailed | Proof generation failed during transaction assembly (wraps ProvingError). |
TransactionEmpty | The transaction contains no operations; add at least one before submission. |
UnfinishedCall | The client started a contract call but did not complete it before building the transaction. |
TransactionProvingError
The following errors occur during the proving phase.
The Proving variant wraps ProvingError, which is an opaque anyhow::Error alias. The Tokio variant wraps std::io::Error and surfaces I/O failures from the async runtime.
| Variant | Description |
|---|---|
LeftoverEntries | The transcript for a contract operation had more entries than the proof consumed. |
MissingKeyset | The proving keys for the required circuit location could not be found. |
Proving | The underlying proving backend returned an error (wraps ProvingError). |
RanOutOfEntries | The transcript for a contract operation ran out of entries before the proof completed. |
Tokio | An I/O error occurred during async proof generation (wraps std::io::Error). |
EventReplayError
Errors encountered during event log replay, used for syncing wallet state from on-chain events.
| Variant | Description |
|---|---|
DtimeUpdateForUntracked | An attempt targeted a DUST generation entry that the client does not track. |
EventForPastTime | An event carries a timestamp earlier than the time the client has already synced to. |
MerkleTreeError | A Merkle tree operation failed during event replay. For more details, see the merkle_tree::InvalidUpdate section. |
NonLinearInsertion | The client inserted events into a Merkle tree non-linearly; the expected index and the received index do not match. |
DustLocalStateError
The following errors occur in local DUST state management on the client side.
| Variant | Description |
|---|---|
BackingNightNotFound | No generation info exists for the given backing NIGHT nonce. |
CommitmentIndexNotFound | No commitment exists for the given commitment index. |
GenerationIndexNotFound | No generation info exists for the given generation index. |
MerkleTreeError | A Merkle tree operation failed during local state management. For more details, see the merkle_tree::InvalidUpdate section. |
NonLinearInsertion | The client inserted values into a Merkle tree non-linearly; the expected and received indices do not match. |
WrongGenerationInfo | The generation info stored for the given index is invalid. |
Cross-reference: Rust error to node error code
When debugging a node error code, find the underlying Rust error by:
- Looking up the numeric
LedgerApiErrorcode in the node error codes reference to find the high-level category. - Checking the node's structured error response body. The Rust error type is often serialized as a string in the
detailorcausefield. - Matching the Rust type name against the tables in this reference.