Move Abort Codes Explained for Sui and Aptos
Move abort codes are the error signals that tell you why a transaction failed on Move-based chains like Sui and Aptos. Unlike Solidity’s revert strings, Move uses unsigned 64-bit integers as error codes, which means the chain returns a number rather than a human-readable message. Understanding how these codes work - and where to look for their meaning - is essential for debugging failed transactions and writing robust smart contracts.
What a move abort code is
An abort is an intentional or unintentional halt of execution in a Move module. When a function calls abort <code> or hits an assert! condition that evaluates to false, the Move VM stops the transaction and returns the specified code. That code is a u64 value, typically defined as a constant in the module’s source code. For example, a module might define const EINSUFFICIENT_BALANCE: u64 = 100; and then call abort EINSUFFICIENT_BALANCE when a balance check fails.
The code itself has no inherent meaning on-chain - it is simply a number. Its meaning comes from the module’s documentation or source code. On Sui, the error is packed into a MoveAbort variant inside the transaction execution error. On Aptos, it appears in the MoveAbortExplanation within the transaction output.
How sui handles abort codes
When a Sui transaction aborts, the response includes a MoveAbort error with two fields: the module’s address and the abort code. The module address is the on-chain ID of the package that caused the abort. You can look up that package’s source on Suiscan, Sui Explorer, or via the CLI with sui client object <package-id> to see the module’s bytecode and - if the developer published source code - the constants and their meanings.
Sui also provides a more readable error message in the transaction effects, but it is generated automatically from the module ID and abort code, not from the developer’s comments. For instance, a failed transfer might show MoveAbort(MoveModuleId { address: 0x2, name: "coin" }, 7). The constant EInvalidArgument in the Sui framework maps to code 7, but custom modules require you to check their source.
To find the meaning of a Sui abort code:
1. Copy the module address from the error.
2. Look it up on a block explorer or via sui client object.
3. If the package is verified, read the source to find the constant definitions.
4. Match the abort code to the constant value.
How aptos handles abort codes
Aptos returns abort codes in transaction outputs as part of the MoveAbortExplanation structure, which includes the module ID and abort code. The Aptos explorer and CLI (aptos account list-transactions) display this clearly. Aptos also supports module upgrades with backward-compatible code, so the same module may have different constant values across versions.
Aptos has a convention: abort codes at specific ranges often indicate standard framework errors. For example, codes below 1000 are reserved for the Aptos standard library. The 0x1::coin module uses codes like ECOIN_VALUE_NOT_SET (1) or ECOIN_ALREADY_SET (2). Custom modules use codes above 1000 by convention, but this is not enforced.
To decode an Aptos abort code:
1. Note the module ID (e.g., 0x1234::my_module).
2. Use the Aptos explorer to view the module’s source if published.
3. Check the module’s constants for the matching code.
4. If the source is not published, you can decompile the bytecode with the Aptos CLI (aptos move decompile --bytecode-path), though this is less readable.
Common abort code sources
Both chains share the same Move language, so certain patterns appear frequently:
- Assertions in standard libraries: Sui’s
0x2::coinand Aptos’s0x1::coinboth abort when you attempt to transfer an insufficient balance. - Access control checks: Modules often define
ENOT_AUTHORIZED(commonly code 2 or 3) when a caller lacks permission. - Resource existence checks:
ERESOURCE_NOT_FOUND(often code 1 or 5) when a required object or account resource does not exist. - Mathematical overflow/underflow: Move’s checked arithmetic ensures overflow aborts with code 0 (the default
abortwithout an explicit code) unless the module usesuncheckedoperations.
Debugging a failed transaction
When you see a transaction failure with an abort code, you have two paths. First, check the chain’s framework source. For Sui, the core framework lives in the Sui GitHub repository under crates/sui-framework/packages. For Aptos, the framework is in the aptos-core repo under aptos-move/framework. These sources list all standard abort codes.
Second, for custom modules, you must have access to the published source or the developer’s documentation. If the module is open-source and verified, the explorer will show it. If not, you cannot reliably interpret the code without contacting the developer.
Writing robust contracts with clear abort codes
If you are developing on either chain, follow these practices:
- Define all abort codes as named constants at the top of your module.
- Use a consistent numbering scheme, such as reserving 0 - 99 for generic errors and 100+ for domain-specific ones.
- Include comments explaining each abort code’s meaning.
- Publish your source code so that users and tools can resolve the codes automatically.
A well-documented module saves everyone time. On both Sui and Aptos, block explorers and development tools can surface these constants if the source is published, turning a cryptic number into a readable error like EINSUFFICIENT_BALANCE instead of 100.
The limits of abort codes
Abort codes are not a full error-reporting system. They carry no dynamic data, so you cannot include the offending value or the caller’s address in the error. For complex validation, you must rely on multiple abort codes to distinguish cases, or log events before aborting. Some developers use a single generic EINVALID_INPUT code and rely on off-chain simulation to catch issues before submission. This works but reduces the usefulness of on-chain error debugging.
In summary, a Move abort code is a simple numeric signal that points you to the module and the specific assertion that failed. Your job as a developer or user is to trace that number back to the source code. On Sui and Aptos, the process is the same in principle, though the tools and explorer interfaces differ slightly. Always check the published source first, and if none exists, you are left guessing - which is why publishing source remains a best practice.
Not financial advice. suiboxer.xyz publishes market data and general information about digital assets. Crypto assets are volatile and you can lose everything you put in. Nothing here is a recommendation to buy, sell or hold, and we make no price predictions.
Prices are sourced from third parties and may be delayed or wrong. Verify anything you intend to act on against a primary source.