This document specifies the error conditions in the FVM and the associated error codes/numbers.
Conventions:
Names in this document match those used in the reference FVM implementation:
UPPER_SNAKE_CASE
names are exit codes.- The
SYS_
prefix namespaces "system" exit codes. - The
USR_
prefix namespaces "user" (or "standard") exit codes.
- The
CamelCase
names are error numbers.
Exit codes are numeric, 32bit integer codes that signal the outcome of the execution.
A 0 exit code (OK
) is an implied exit code: it is generated when the actor returns normally. This is the only exit code that can carry a return value (an arbitrary IPLD object).
Non-zero exit code are either:
- explicitly signalled by an actor through an early
abort
operation - explicitly generated by the VM because it encountered an abnormality during execution
In both cases, a non-zero exit code indicates that execution was interrupted and that the actors state was left unchanged. A non-zero exit code may not be accompanied by a return value.
Exit codes appear on-chain inside the message receipt, and therefore form part of consensus.
System non-zero exit codes are generated by the VM itself to indicate that the message itself failed
to apply. Actors may not call vm::abort
with any system exit code.
Code | Status | Description |
---|---|---|
1 | SYS_SENDER_INVALID |
sender doesn't exist |
2 | SYS_SENDER_STATE_INVALID |
message sender is not in a valid state to send the message |
3 | reserved | |
4 | SYS_ILLEGAL_INSTRUCTION |
message receiver trapped |
5 | SYS_INVALID_RECEIVER |
receiver doesn't exist and can't be automatically created |
6 | SYS_INSUFFICIENT_FUNDS |
sender didn't have the requisite funds |
7 | SYS_OUT_OF_GAS |
out of gas |
8 | reserved | |
9 | SYS_ILLEGAL_EXIT_CODE |
message receiver aborted with an system exit code |
10 | SYS_ASSERTION_FAILED |
some internal assertion failed |
11 | SYS_MISSING_RETURN |
the actor returned a block handle that doesn't exist |
13-15 | reserved |
Notes:
- If a message sender doesn't exist on-chain, the VM will return a receipt with the
SYS_SENDER_INVALID
exit code. - If an actor calls
vm::abort
with a system exit code, that exit code will be replaced withSYS_ILLEGAL_EXIT_CODE
. - If an actor traps (often a memory violation), the exit code
SYS_ILLEGAL_INSTRUCTION
will be returned. User-level assertions (e.g., a go/rust panic, an uncaught exception, etc.) should cleanly abort withUSR_ASSERTION_FAILED
.SYS_ILLEGAL_INSTRUCTION
means that the actor failed in a way that it couldn't (or didn't) handle itself. - If a message runs out of gas, the VM will return a receipt with the
SYS_OUT_OF_GAS
exit code. - Most of these exit codes are only reflected on-chain and will not be observed in internal sends.
The exceptions are:
SYS_ILLEGAL_EXIT_CODE
if the called actor aborted with a system exit code.SYS_ILLEGAL_INSTRUCTION
if the called actor crashed.SYS_MISSING_RETURN
if the actor returns an invalid block handle.
Changes from pre-FVM Filecoin:
- Removed
SYS_INVALID_METHOD
(3). Dispatch is now handled inside actor code which should exit with the equivalentUSR_UNHANDLED_MESSAGE
. - Removed
SYS_FORBIDDEN
(8). Caller verification is a userspace operation, we'll now exit withUSR_FORBIDDEN
. - Replaced
SYS_ILLEGAL_ARGUMENT
withSYS_ASSERTION_FAILED
to more accurately reflect its usage. When this appears on-chain, it means that a message hit some internal Filecoin assert that shouldn't happen.
Standard non-zero exit codes are codes returned by actors to indicate common failure conditions.
Code | Status | Description |
---|---|---|
16 | USR_ILLEGAL_ARGUMENT |
invalid message parameters |
17 | USR_NOT_FOUND |
message referenced something that doesn't exist |
18 | USR_FORBIDDEN |
operation forbidden |
19 | USR_INSUFFICIENT_FUNDS |
insufficient funds for operation |
20 | USR_ILLEGAL_STATE |
the actor is in an illegal state |
21 | USR_SERIALIZATION |
actor failed to serialize or deserialize some state |
22 | USR_UNHANDLED_MESSAGE |
actor cannot handle this message |
23 | USR_UNSPECIFIED |
the actor failed with an unspecified error |
24 | USR_ASSERTION_FAILED |
the actor failed some user-level assertion |
25-31 | reserved |
Changes from pre-FVM Filecoin:
- Added
USR_UNHANDLED_MESSAGE
(replacingSYS_INVALID_METHOD
). - Added
USR_UNSPECIFIED
. This indicates that something unspecified went wrong, but we don't know what the cause is. This is a sane default exit code when accurately determining the underlying error is expensive, unreliable, complex, etc. - Added
USR_ASSERTION_FAILED
. This means that the actor failed some user-level assertion (e.g., the actor paniced, threw an uncaught exception, etc.).
Syscall error numbers (ErrorNumber
) are returned by syscalls to actors. They indicate that the
syscall failed (without any side effects). The actor may choose to handle the error and continue, or
abort (usually with one of the standard non-zero exit codes).
A return value of "0" means that the syscall succeeded.
Number | Name | Description |
---|---|---|
1 | IllegalArgument |
invalid syscall parameters |
2 | IllegalOperation |
actor is not in the correct state to perform operation |
3 | LimitExceeded |
some limit was exceeded (e.g. lookback limit) |
4 | AssertionFailed |
some internal assertion failed |
5 | InsufficientFunds |
attempted to send more than balance |
6 | NotFound |
resource not found |
7 | InvalidHandle |
block handle invalid |
8 | IllegalCid |
cid creation parameters (hash/length) were invalid |
9 | IllegalCodec |
specified codec is not allowed |
10 | Serialization |
block format did not match specified codec |
11 | Forbidden |
operation is forbidden |
Changes from pre-FVM Filecoin:
Before the FVM, Filecoin didn't have a concept of syscall error numbers, only exit codes. However:
-
Pre-FVM, most syscalls returned string errors with no exit codes attached.
-
There is no reliable mapping from syscall errors to exit codes. For example:
- If a syscall returns
IllegalArgument
, it means that an illegal argument was passed to the syscall. - If an actor exits with
USR_ILLEGAL_ARGUMENT
, it means the message parameters weren't allowed.
1 does not imply 2. An actor may pass illegal arguments to a syscall due to a bug in the actor, illegal state, etc.
- If a syscall returns
Notes:
-
We intentionally use
IllegalArgument
instead ofSerialization
in non-IPLD syscalls, even if we're using CBOR. -
AssertionFailed
is a special error that indicates that some internal assertion failed and that there is likely something wrong with a system actor or the Filecoin state-tree itself. It exists to allow the network to continue in the face of bugs where the network continuing is likely less harmful than the bug itself.It can't be caught by normal actors (and turns into a
SYS_ASSERTION_FAILED
exit code on-chain), but may be caught by some system actors (e.g., cron).Uses:
actor::create_actor
fails because the init actor is in a bad state.actor::resolve_address
fails because the init actor is in a bad state.
Error | Reason |
---|---|
NotFound |
when the target block isn't in the reachable set. |
IllegalArgument |
if there's something wrong with the CID. |
Error | Reason |
---|---|
LimitExceeded |
if the block is too big. |
NotFound |
one of the blocks's children isn't in the reachable set |
IllegalCodec |
if the passed codec isn't supported. |
Serialization |
if the passed block doesn't match the passed codec. |
IllegalArgument |
if the block isn't in memory, etc. |
Error | Reason |
---|---|
InvalidHandle |
if the handle isn't known. |
IllegalArgument |
if the passed buffer isn't valid, in memory, etc. |
Error | Reason |
---|---|
InvalidHandle |
if the handle isn't known. |
Error | Reason |
---|---|
InvalidHandle |
if the handle isn't known. |
IllegalCid |
hash code and/or hash length aren't supported. |
IllegalArgument |
if the passed buffer isn't valid, in memory, etc. |
Error | Reason |
---|---|
IllegalOperation |
actor hasn't set the root yet, or has been deleted. |
IllegalArgument |
if the passed buffer isn't valid, in memory, etc. |
Error | Reason |
---|---|
IllegalOperation |
actor has been deleted |
NotFound |
specified root CID is not in the reachable set. |
Error | Reason |
---|---|
NotFound |
beneficiary isn't found |
Forbidden |
beneficiary is not allowed (usually means beneficiary is self) |
IllegalArgument |
if the passed address buffer isn't valid, in memory, etc. |
Cannot fail.
Cannot fail.
Error | Reason |
---|---|
NotFound |
target actor doesn't exist |
IllegalArgument |
if the passed address buffer isn't valid, in memory, etc. |
Error | Reason |
---|---|
NotFound |
target actor doesn't exist |
IllegalArgument |
if the passed address buffer isn't valid, in memory, etc. |
TODO (likely needs to go)
TODO
Error | Reason |
---|---|
IllegalArgument |
signature, address, or plaintext buffers are invalid. |
Error | Reason |
---|---|
IllegalArgument |
invalid buffer |
Error | Reason |
---|---|
IllegalArgument |
anything |
Error | Reason |
---|---|
IllegalArgument |
anything |
Error | Reason |
---|---|
IllegalArgument |
everything else |
Error | Reason |
---|---|
LimitExceeded |
exceeded lookback limit finding block. |
IllegalArgument |
something else |
Error | Reason |
---|---|
LimitExceeded |
exceeds seal aggregation limit. |
IllegalArgument |
something is malformed |
Error | Reason |
---|---|
IllegalArgument |
if malformed params |
Error | Reason |
---|---|
LimitExceeded |
lookback exceeds limit. |
IllegalArgument |
invalid buffer, etc. |
Error | Reason |
---|---|
IllegalArgument |
invalid name buffer. |
A syscall error in send means the caller did something wrong. If the callee panics, exceeds some limit, aborts, aborts with an invalid code, etc., the syscall will succeed and the failure will be reflected in the exit code contained in the syscall's return value.
Error | Reason |
---|---|
NotFound |
target actor does not exist and cannot be created. |
InsufficientFunds |
tried to send more FIL than available. |
InvalidHandle |
parameters block not found. |
LimitExceeded |
recursion limit reached. |
IllegalArgument |
invalid recipient address buffer. |