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:
- Fund your account with STRK or ETH
- For testnet, use the Starknet Faucet
- 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
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:
- Verify parameter order matches constructor signature
- Check ByteArray encoding (length, data, pending_word, pending_len)
- 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:
- Peer set incorrectly on either chain
- Using Object ID instead of contract address
- 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
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:
- Check LayerZero Scan for the transaction details
- Look for the
LzReceiveAlert event
- Decode the
reason array for error details
- 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