Common Errors on Starknet
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
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:
- 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 cross-chain:
// 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);
Cross-Chain 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
LzReceiveAlertevent - Decode the
reasonarray 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 cross-chain 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
- FAQ - Frequently asked questions
- Protocol Overview - Message lifecycle
- Configuration Guide - Security setup
- Discord - Community support