Skip to main content

Build Errors

WASM Compilation Failure

Error Message:
Cause: Soroban contracts target wasm32v1-none which is a no_std environment. Using standard library features that aren’t available. Solution: Ensure your contract crate uses #![no_std]:
And verify the WASM target is installed:

Missing WASM Target

Error Message:
Cause: The WASM compilation target is not installed in your Rust toolchain. Solution:

Deployment Errors

Insufficient Funds

Error Message:
Cause: Your account doesn’t have enough XLM to cover the deployment transaction fees and contract storage rent. Solution: Fund your testnet account:
For mainnet, ensure sufficient XLM balance for the deployment plus storage rent deposit.

Contract Already Exists

Error Message:
Cause: A contract with the same deployer/source account and salt already exists at the computed address. Solution: Use a different salt or deployer account. Contract addresses are deterministic based on the deployer and salt.

Constructor Failed

Error Message:
Cause: The constructor arguments are invalid or a dependency (e.g., endpoint address) is incorrect. Solution: Verify constructor arguments match the contract type: OApp: owner, endpoint, delegate
  • endpoint must be a valid, deployed Endpoint V2 contract
  • owner and delegate must be valid addresses
OFT: token, shared_decimals, oft_type, endpoint, delegate
  • token must be a valid SEP-41 token contract
  • shared_decimals must be ≤ the token’s local decimals
  • endpoint must be a valid, deployed Endpoint V2 contract
  • delegate must be a valid address (serves as the initial owner)

Configuration Errors

No Peer Set

Error Code: 2001 (NoPeer) Cause: Attempted to send a message to a destination that has no configured peer. Solution:

Only Peer

Error Code: 2002 (OnlyPeer) Cause: Received a message from an address that doesn’t match the configured peer for the source chain. Solution: Verify that the peer address set on this chain matches the actual contract address on the remote chain. Peer addresses must be in 32-byte format (left-padded with zeros for EVM addresses).

Invalid Options

Error Code: 2000 (InvalidOptions) Cause: Enforced options or caller options are malformed or not Type 3 format. Solution: Ensure options follow Type 3 format. Only Type 3 options can be combined. Check that enforced options are set correctly for the destination and message type.

OFT Errors

Slippage Exceeded

Error Code: 3005 (SlippageExceeded) Cause: The received amount after fees and dust removal is below min_amount_ld. Solution: Decrease the min_amount_ld value in your SendParam to allow more slippage tolerance, or reduce OFT fees. Use quote_oft to preview the expected receipt before sending:

Invalid Amount

Error Code: 3001 (InvalidAmount) Cause: amount_ld or min_amount_ld is negative. Solution: Ensure both amount_ld and min_amount_ld in SendParam are non-negative.

Paused

Error Code: 3110 (Paused) Cause: The OFT is paused. All send, receive, and quote operations are blocked. Solution: Call unpause from an account that has UNPAUSER_ROLE:

Rate Limit Exceeded

Error Code: 3120 (ExceededRateLimit) Cause: The transfer amount exceeds the configured rate limit capacity. Solution: Wait for capacity to replenish (tokens decay linearly over the configured window), or adjust the rate limit:

Endpoint Errors

Unauthorized

Error Code: 22 (Unauthorized) Cause: The caller is not authorized to perform the action. Could be: not the owner, not the delegate, not the registered library, or require_auth() was not satisfied. Solution: Verify you’re calling from the correct account (owner or delegate) and that your transaction includes the proper authorization.

Path Not Initializable

Error Code: 18 (PathNotInitializable) Cause: The OApp’s allow_initialize_path returned false for the given origin. This means the sender is not a configured peer. Solution: Set the peer on the receiving OApp for the source chain’s endpoint ID.

Payload Hash Not Found

Error Code: 20 (PayloadHashNotFound) Cause: Attempting to clear a message that hasn’t been verified yet, or the payload hash doesn’t match. Solution: Wait for DVN verification to complete before attempting delivery. Use uln302.verifiable(packet_header, payload_hash) to check whether DVNs have reached quorum. If the message is already verifiable but clear still fails, verify that the guid and message exactly match the stored payload, because endpoint.verifiable(origin, receiver) only confirms path and nonce state and does not validate the payload hash used by clear.

ULN-302 Errors

Invalid Config

Error Code: 6 (InvalidConfig) Cause: ULN configuration is malformed (e.g., no DVNs specified, invalid threshold). Solution: Ensure at least one DVN is configured (required or optional). The optional_dvn_threshold must be ≤ the number of optional DVNs.

Duplicate DVNs

Error Code: 5 (DuplicateRequiredDVNs) or 4 (DuplicateOptionalDVNs) Cause: The same DVN address appears multiple times in the configuration. Solution: Remove duplicate DVN addresses from your configuration.

Common Gotchas

TTL Extension During lz_receive

TTL extension during lz_receive introduces additional fees. Ensure the executor gas budget accounts for TTL extension overhead.

Reentrancy Prohibition

Soroban prohibits reentrancy — contracts cannot call themselves (directly or indirectly) in the same transaction. This is why LayerZero uses pull mode for message delivery: the executor calls OApp.lz_receive() directly, and the OApp calls endpoint.clear() internally to verify and clear the payload. This avoids the Endpoint -> OApp -> Endpoint reentrancy that would occur if the Endpoint delivered messages to the OApp directly.

Error Code Reference

Endpoint (1–25)

OApp (2000–2003)

OFT Core (3000–3005)

OFT Fee Extension (3100–3102)

OFT Pausable Extension (3110–3111)

OFT Rate Limiter Extension (3120–3124)

ULN-302 (1–21)

Debugging Tips

  1. Check error codes: Soroban errors include a numeric code. Match it against the error code tables in this page or the contract source.
  2. Simulate first: Use stellar contract invoke with --send=no to simulate a transaction without submitting it. This reveals errors before spending fees.
  3. Check events: Use stellar events or the RPC’s getEvents method to inspect emitted events for debugging.
  4. Verify peers: Most “message rejected” errors come from misconfigured peers. Always verify peers are set on both sides.
  5. Check TTLs: For “entry not found” errors on entries that should exist, the entry may have been archived due to TTL expiry.

Next Steps