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 |
12-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.
- The VM raises fatal errors when it encounters system-level unexpected condition during message
execution. These errors are severe, and usually indicate a correctness flaw. Either something
is found to be broken at runtime (e.g. state tree cannot be decoded, init actor is not found,
etc.), or we've hit some kind of programming error. When this happens, the VM produces a consensus
outcome by stamping the
SYS_ASSERTION_FAILED
exit code on the receipt of the offending message. For context, read filecoin-project/ref-fvm#508.
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 |
12 | BufferTooSmall |
the output buffer is too small |
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. This error isn't currently used.