Transaction & Account Errors
Common errors when sending transactions and managing accounts on Algorand.
Table of Contents
Transaction Errors
Overspend
TransactionPool.Remember: transaction TXID: overspend (account ADDRESS, data {_struct:{} Status:Offline MicroAlgos:{Raw:1000} ...})
Cause: Sender account has insufficient balance for amount + fee + minimum balance.
Minimum balance requirements:
| Item | MBR |
|---|---|
| Base account | 100,000 microAlgo |
| Each opted-in asset | +100,000 microAlgo |
| Each created asset | +100,000 microAlgo |
| Each opted-in app | +100,000 microAlgo |
| Each created app | +100,000 microAlgo |
| App local state per schema | Varies |
| Box storage | 2,500 + 400 * size |
Fix:
- Fund the sender account
- Reduce transaction amount
- Account for MBR when calculating available balance:
# Calculate available balance
account_info = algorand.account.get_information(address)
available = account_info.amount - account_info.min_balance
Transaction Already in Ledger
TransactionPool.Remember: transaction already in ledger: TXID
Cause: Duplicate transaction submitted (same txn ID).
Common causes:
- Retrying a transaction that already succeeded
- Using same lease within validity window
- Network latency causing duplicate submission
Fix: Check if transaction exists before retrying:
try {
const result = await algorand.client.algod.pendingTransactionInformation(txId).do()
// Transaction exists
} catch {
// Safe to retry
}
Transaction Pool Full
TransactionPool.Remember: transaction pool is full
Cause: Node's transaction pool at capacity.
Fix:
- Wait and retry with exponential backoff
- Increase fee to prioritize transaction
- Try a different node
Fee Too Low
TransactionPool.Remember: transaction TXID: fee X below threshold Y
Cause: Transaction fee below minimum (usually 1000 microAlgo).
Fix:
algorand.send.payment(PaymentParams(
sender=sender,
receiver=receiver,
amount=AlgoAmount(algo=1),
static_fee=AlgoAmount(micro_algo=1000), # Minimum fee
))
Round Out of Range
TransactionPool.Remember: transaction TXID: round X outside of Y-Z range
Cause: Transaction's validity window expired or is in the future.
Fix:
// Set appropriate validity window
await algorand.send.payment({
sender: sender,
receiver: receiver,
amount: algo(1),
validityWindow: 1000, // Valid for 1000 rounds (~1 hour)
})
Invalid Group
TransactionPool.Remember: transaction TXID: bad group assignment
Cause: Transaction claims to be part of a group but has wrong group ID.
Fix: Use AlgoKit Utils for proper grouping:
// Correct grouping
await algorand
.newGroup()
.addPayment({ sender, receiver, amount: algo(1) })
.addAssetOptIn({ sender, assetId: 12345n })
.send()
Group Size Limit
cannot send transaction group with more than 16 transactions
Cause: Transaction group exceeds 16 transaction limit.
Fix: Split into multiple groups or optimize to fewer transactions.
Asset Errors
Asset Not Found
asset ASSET_ID does not exist
Cause: Asset ID doesn't exist on the network.
Common causes:
- Wrong network (TestNet vs MainNet)
- Asset was deleted
- Typo in asset ID
Fix: Verify asset exists:
const assetInfo = await algorand.client.algod.getAssetByID(assetId).do()
Asset Not Opted In
asset ASSET_ID missing from ACCOUNT_ADDRESS
Cause: Receiving account hasn't opted into the asset.
Fix: Opt in before transfer:
algorand.send.asset_opt_in(AssetOptInParams(
sender=receiver_address,
asset_id=asset_id,
))
Asset Frozen
asset ASSET_ID frozen in ACCOUNT_ADDRESS
Cause: Account's holding of this asset is frozen.
Fix: Asset freeze manager must unfreeze the account.
Clawback Not Authorized
only clawback address can clawback
Cause: Attempting clawback without being the clawback address.
Fix: Only the designated clawback address can perform clawbacks.
Cannot Close Asset
cannot close asset: ACCOUNT_ADDRESS still has X units
Cause: Trying to opt out while still holding units.
Fix: Transfer all units before opting out:
# First transfer all units
algorand.send.asset_transfer(AssetTransferParams(
sender=account,
receiver=creator_or_other,
asset_id=asset_id,
amount=balance, # All remaining
))
# Then opt out
algorand.send.asset_opt_out(AssetOptOutParams(
sender=account,
asset_id=asset_id,
creator=creator_address,
))
Account Errors
Account Not Found
account ADDRESS not found
Cause: Account doesn't exist (never funded).
Note: Algorand accounts must receive at least minimum balance to exist.
Fix: Fund the account:
algorand.send.payment(PaymentParams(
sender=funder.address,
receiver=new_account.address,
amount=AlgoAmount(micro_algo=100_000), # Minimum
))
Invalid Address
invalid address: ADDRESS
Cause: Malformed Algorand address.
Valid address format:
- 58 characters
- Base32 encoded
- Includes checksum
Verify address:
import { isValidAddress } from 'algosdk'
if (!isValidAddress(address)) {
throw new Error('Invalid address')
}
Wrong Network
genesis hash mismatch
Cause: Transaction built for different network than target.
Fix: Ensure AlgorandClient connects to correct network:
// For TestNet
const algorand = AlgorandClient.testNet()
// For MainNet
const algorand = AlgorandClient.mainNet()
// Check network
const params = await algorand.client.algod.getTransactionParams().do()
console.log('Network:', params.genesisID) // testnet-v1.0, mainnet-v1.0
SDK Errors
AlgodHTTPError
AlgodHTTPError: Network request error. Received status 401
Common status codes:
| Status | Meaning | Fix |
|---|---|---|
| 401 | Unauthorized | Check API token |
| 404 | Not found | Check server URL |
| 500 | Server error | Node issue, retry |
| 503 | Unavailable | Node overloaded, retry |
Fix for 401:
algorand = AlgorandClient.from_config(
algod_config=AlgoClientNetworkConfig(
server="https://testnet-api.algonode.cloud",
port="443",
token="", # AlgoNode doesn't require token
)
)
Timeout Waiting for Confirmation
Timeout waiting for transaction TXID to be confirmed
Cause: Transaction not confirmed within wait rounds.
Possible reasons:
- Transaction rejected (check node logs)
- Fee too low during congestion
- Network issues
Fix: Increase wait time or check status:
const result = await algorand.send.payment(
{ sender, receiver, amount: algo(1) },
{ maxRoundsToWaitForConfirmation: 10 } // Wait longer
)
Connection Refused
fetch failed: ECONNREFUSED
Cause: Cannot connect to Algorand node.
Fix:
- For LocalNet: Ensure AlgoKit LocalNet is running (
algokit localnet start) - For public networks: Check internet connection
- Verify server URL is correct
Application Errors
Application Not Found
application APPID does not exist
Cause: App ID doesn't exist on the network.
Fix: Verify app exists or deploy it:
const appInfo = await algorand.client.algod.getApplicationByID(appId).do()
Not Opted Into Application
address ADDRESS has not opted in to application APPID
Cause: Account trying to access local state without opt-in.
Fix:
algorand.send.app_call(AppCallParams(
sender=user_address,
app_id=app_id,
))
Application Creator Only
cannot update or delete application: only creator can modify
Cause: Attempting to modify app without being creator.
Fix: Only the app creator can update/delete. Check creator:
app_info = algorand.app.get_by_id(app_id)
if sender != app_info.creator:
raise Error("Only creator can modify")
Debugging Tips
Enable Verbose Logging
import { Config } from '@algorandfoundation/algokit-utils'
Config.configure({ debug: true })
Check Transaction Status
// Check pending transaction
const pending = await algorand.client.algod.pendingTransactionInformation(txId).do()
console.log('Pool error:', pending.poolError)
// Check confirmed transaction
const confirmed = await algorand.client.indexer.lookupTransactionByID(txId).do()
Simulate Before Sending
const result = await algorand
.newGroup()
.addPayment({ sender, receiver, amount: algo(1) })
.simulate()
if (result.simulateResponse.txnGroups[0].failureMessage) {
console.error('Would fail:', result.simulateResponse.txnGroups[0].failureMessage)
}