Skip to main content
This guide catalogs common errors encountered when developing and deploying LayerZero contracts on Starknet, with explanations and solutions.

Account Errors

Account Not Deployed

Error:
Account contract at address 0x... is not deployed
Cause: You’re trying to use an account that hasn’t been deployed yet. On Starknet, accounts are smart contracts that must be deployed before use. Solution:
# 1. Check if account is created
sncast account list

# 2. Fund the computed address with STRK/ETH

# 3. Deploy the account
sncast account deploy \
  --name your_account \
  --url <YOUR_SEPOLIA_RPC_URL>

Insufficient Balance for Fee

Error:
Insufficient balance for fee. Required: X, Available: Y
Cause: Your account contract doesn’t have enough STRK or ETH to pay transaction fees. Solution:
  1. Fund your account with STRK or ETH
  2. For testnet, use the Starknet Faucet
  3. For mainnet, bridge funds via Starkgate

Account Prefunding Required

Error:
Transaction reverted: Insufficient funds for transaction
Cause: Before deploying an account contract, the computed address must be funded. Starknet computes the address deterministically, so you can fund it before deployment. Solution:
# 1. Create account (doesn't deploy yet)
sncast account create --name my_account --type oz
# Output shows: Address: 0x123...

# 2. Fund that address BEFORE deploying

# 3. Then deploy
sncast account deploy --name my_account

Declare Errors

Class Already Declared

Error:
Class with hash 0x... is already declared
Cause: You’re trying to declare a contract class that already exists on the network. Solution:
# Use the existing class_hash instead
sncast deploy --class-hash <EXISTING_HASH> --arguments '...'

# Or if you modified the contract, rebuild to get a new hash
scarb clean && scarb build

Compilation Failed

Error:
error: could not compile `my_contract` due to previous errors
Cause: Cairo compilation errors in your contract. Solution:
# Check compilation errors
scarb build 2>&1 | less

# Common issues:
# - Missing imports
# - Type mismatches
# - Trait bound errors

Deploy Errors

Wrong Owner (UDC Footgun)

Error: After deployment, the owner is set to an unexpected address (the UDC address). Cause: When deploying via the Universal Deployer Contract (UDC), get_caller_address() in the constructor returns the UDC address, not your account. Wrong pattern:
#[constructor]
fn constructor(ref self: ContractState, endpoint: ContractAddress) {
    // BUG: This sets UDC as owner!
    self.ownable.initializer(get_caller_address());
}
Solution:
#[constructor]
fn constructor(
    ref self: ContractState,
    endpoint: ContractAddress,
    owner: ContractAddress,  // Pass owner explicitly
) {
    self.ownable.initializer(owner);
}

Invalid Constructor Calldata

Error:
Entry point EntryPointSelector(0x...) not found in contract
or
Failed to deserialize param
Cause: Constructor calldata doesn’t match the expected parameters. Solution:
  1. Verify parameter order matches constructor signature
  2. Check ByteArray encoding (length, data, pending_word, pending_len)
  3. Verify felt252 encoding for addresses and numbers
# Example: constructor(endpoint, owner, native_token)
sncast deploy \
  --class-hash 0x... \
  --network sepolia \
  --arguments '<ENDPOINT_ADDRESS>, <OWNER_ADDRESS>, <NATIVE_TOKEN_ADDRESS>'

Resource Bounds Exceeded

Error:
Insufficient max fee. Required: X, Provided: Y
or
Transaction execution failed: resource bounds exceeded
Cause: The transaction requires more resources than your specified limits. Solution:
# Increase fee cap (tooling derives resource bounds)
sncast deploy \
  --class-hash 0x... \
  --network sepolia \
  --arguments '...' \
  --max-fee <MAX_FEE_IN_FRI>  # Fee cap used to derive resource bounds
1 STRK = 10^18 fri

Configuration Errors

Peer Not Set

Error:
Assertion failed: peer not set
Cause: Attempting to send a message to a chain without a configured peer. Solution:
# Set peer for destination chain
sncast invoke \
  --contract-address <YOUR_OAPP> \
  --function set_peer \
  --network sepolia \
  --arguments '<DST_EID>, (<PEER_ADDRESS_HIGH>, <PEER_ADDRESS_LOW>)'
Remember: Peers must be set bidirectionally on both chains.

Invalid Peer

Error:
Assertion failed: invalid peer
Cause: Received a message from an address that doesn’t match the configured peer. Causes:
  1. Peer set incorrectly on either chain
  2. Using Object ID instead of contract address
  3. Peer not set at all on sending chain
Solution:
// Verify peer configuration
let peer = oft.get_peer(src_eid);
// Compare with expected remote contract address

Library Not Set

Error:
No library configured for eid: X
Cause: No send or receive library configured for the pathway. Solution: Use default libraries or set custom ones:
// Usually defaults are sufficient
// If you need custom libraries:
endpoint.set_send_library(oapp, dst_eid, library_address);

Serialization Errors

Felt Overflow

Error:
Value does not fit in felt252
Cause: Attempting to store a value larger than ~2^251 in a felt252. Solution:
// Use u256 for large numbers
let big_value: u256 = 1000000000000000000000000_u256;

// When encoding for crosschain:
// u256 is serialized as two felt252 (low, high)

ByteArray Encoding Error

Error:
Failed to deserialize ByteArray
Cause: Incorrect ByteArray encoding in calldata. ByteArray structure:
[
  pending_word_len,    // Number of bytes in pending_word
  data_len,            // Number of 31-byte chunks
  data[0..data_len],   // Full 31-byte chunks
  pending_word         // Remaining bytes (< 31)
]
Solution: For short strings (< 31 bytes), use simplified encoding with --arguments:
# "MyToken" as a ByteArray using --arguments
sncast invoke ... --arguments '"MyToken"'
When using --arguments, sncast handles ByteArray encoding automatically. You can pass strings directly in quotes.

Execution Errors

Unauthorized

Error:
Assertion failed: unauthorized
or
Caller is not the owner
Cause: Calling an owner-only function from a non-owner account. Solution:
# Ensure you're using the owner account
sncast invoke \
  --account owner_account \
  --contract-address <CONTRACT> \
  --function set_peer \
  --network sepolia \
  --arguments '<DST_EID>, (<PEER_HIGH>, <PEER_LOW>)'

Contract Not Pausable

Error:
Assertion failed: contract is paused
Cause: Calling a function on a paused contract. Solution:
# Unpause the contract (owner or PAUSE_MANAGER_ROLE)
sncast invoke \
  --account admin \
  --contract-address <CONTRACT> \
  --function unpause

Rate Limit Exceeded

Error:
Rate limit exceeded for eid: X
Cause: Transfer volume exceeds configured rate limits (OFTMintBurnAdapter). Solution:
// Check current rate limit config
let limit = oft.get_rate_limit(eid, direction);

// Increase limits if needed (RATE_LIMITER_MANAGER_ROLE)
oft.set_rate_limits(new_limits, direction);

Crosschain Errors

Insufficient Fee

Error:
Insufficient fee. Required native: X, Supplied: Y
Cause: Not enough tokens approved or sent for LayerZero messaging fees. Solution:
// 1. Quote the fee first
let fee = oft.quote_send(send_param, false);

// 2. Approve sufficient amount
native_token.approve(oft_address, fee.native_fee + buffer);

// 3. Send with correct fee
oft.send(send_param, fee, refund_address);

Slippage Exceeded

Error:
Slippage exceeded. Received: X, Minimum: Y
Cause: After dust removal and fees, the received amount is less than min_amount_ld. Solution:
// Quote first to see actual amounts
let quote = oft.quote_oft(send_param);

// Adjust min_amount_ld to account for:
// - Dust removal
// - Fees (if using OFTMintBurnAdapter)
let safe_min = quote.receipt.amount_received_ld * 99 / 100;  // 1% buffer

Message Execution Failed

Error (on LayerZero Scan):
LzReceiveAlert: execution failed
Cause: The destination contract’s _lz_receive reverted. Debug Steps:
  1. Check LayerZero Scan for the transaction details
  2. Look for the LzReceiveAlert event
  3. Decode the reason array for error details
  4. Simulate the transaction locally
Common causes:
  • Insufficient gas (increase enforced options)
  • Contract paused on destination
  • Rate limit exceeded
  • Application logic error

Build Errors

Missing Dependencies

Error:
error: cannot find crate `layerzero`
Cause: Dependencies not properly configured in Scarb.toml. Solution:
[dependencies]
starknet = "2.14.0"
openzeppelin = "2.0.0"
lz_utils = { path = "./node_modules/@layerzerolabs/protocol-starknet-v2/libs/lz_utils" }
layerzero = { path = "./node_modules/@layerzerolabs/protocol-starknet-v2/layerzero" }
Install the LayerZero Starknet package first: npm install @layerzerolabs/protocol-starknet-v2

Version Mismatch

Error:
Incompatible Cairo version. Expected: 2.8.2, Found: 2.7.0
Cause: Scarb/Cairo version doesn’t match project requirements. Solution:
# Check current version
scarb --version

# Install correct version (check Scarb.toml for required version)
asdf install scarb 2.14.0
asdf local scarb 2.14.0

Debugging Tips

1. Use LayerZero Scan

Track your crosschain transactions at LayerZero Scan.

2. Check Transaction Status

sncast tx-status <TRANSACTION_HASH>

3. Simulate Locally

Test your logic with snforge test before deploying.

4. Increase Verbosity

sncast invoke ... --json 2>&1 | jq .

5. Check Events

Query contract events via block explorer or RPC:
# Using starkli or similar tools
starkli events --from-block 12345 --to-block latest --address <CONTRACT>

Next Steps