Error Codes
Common Causes
Error Reference
Every error below is returned by the program as an Anchor custom error. The numbers match the table above. Each entry lists the instructions and conditions that raise it, as of release 0.1.0, and how to fix it. Errors that no instruction returns in this release are marked as such. The Anchor framework errors that account constraints can return are in Anchor Framework Errors.Math and Parameters
-
MathOverflow(6000)- A checked calculation overflows, underflows or divides by zero. This covers fixed-point price math, liquidity and fee math, and Token 2022 transfer fee math (an amount plus its transfer fee that does not fit in
u64). remove_liquidityasks for more liquidity from a range slot than the slot holds unlocked. The program has anInsufficientLiquidityerror, but release 0.1.0 never returns it, and this one fires instead.add_liquidity_by_weighthas amultipliertimes a weight that does not fit inu128.set_reward_emissionhasend_timebelow the open time.- Fix: Check amounts against the position state before sending, and use smaller
multipliervalues and liquidity amounts.
- A checked calculation overflows, underflows or divides by zero. This covers fixed-point price math, liquidity and fee math, and Token 2022 transfer fee math (an amount plus its transfer fee that does not fit in
-
TypeCastFailed(6001)- A byte that must be an enum value is out of range.
collect_fee_modemust be 0 or 1 ininitialize_pool_with_dynamic_config,initialize_launch_poolandcreate_static_config, andactivation_typemust be 0 or 1 increate_static_config. - A value does not fit its target type during a calculation, such as the liquidity derived by
add_liquidity_imbalanceexceedingu128or a scheduled base fee result exceedingu64. - Fix: Send valid enum values and keep prices, liquidity and amounts inside the documented ranges.
- A byte that must be an enum value is out of range.
-
InvalidParameters(6037)- Pool creation (
initialize_pool_with_dynamic_config,initialize_launch_pool) andcreate_static_config:tick_spacingis 0 or above 256, orextensionshas a bit other than the two defined.create_static_configalso rejects the ActivationAccess bit. - Pool creation:
initial_sqrt_priceis outside the square root price bounds. With a static config the price must also map to a tick id inside the tick id bounds. - Fee settings in pool creation and config creation: a base fee, or the lowest or highest fee of a scheduled base fee, outside 0.01 percent to 99 percent; a time scheduler with a zero
period_frequency,reduction_factorornumber_of_period; a market cap scheduler with a zeroreduction_factor,sqrt_price_step_bps,scheduler_expiration_durationornumber_of_period; non-zero padding bytes indata. - Dynamic fee settings:
max_volatility_accumulatororvariable_fee_controlabove 16777215,filter_periodof 0 or not belowdecay_period,decay_periodabove 3600,reduction_factorof 0 or above 10000,min_delta_tick_for_significant_swapof 0, or a highest variable fee above 99 percent. - ActivationAccess pools:
pool_activationmissing, the two activation modes, in slot order, not one of Open then Open, Open then BondingCurve, Open then TimeBased, or BondingCurve then TimeBased, or mode data that does not validate (non-zero padding; BondingCurve without a non-defaultwhitelisted_add_liquidity, withis_reach_targetset, withtarget_increase_bpsof 10000 or less, or with a target price above the highest usable tick; TimeBased points in the past or more than 30 days ahead, oractivation_pointdifferent fromswap_point). Without a TimeBased slot,activation_pointmust be the current slot or timestamp. Pools without the extension must omit bothactivation_pointandpool_activation. create_dynamic_config:permissionabove 1,partner_fee_bpsabove 5000, orpool_creator_authorityequal to the default key.close_config: both or neither of the static and dynamic config accounts are passed.set_pool_status:statusabove 3, or equal to the current status.update_partner_fee:partner_fee_bpsabove 5000, or the pool has no partner.initialize_tick_array: the index covers no usable tick id inside the tick id bounds.increase_oracle_length:length_to_addis 0 or the new length would exceed 500.open_positionandexpand_position:tick_rangesis empty, the position would exceed 45 range slots, a range hastick_lower_idnot belowtick_upper_id, or an id is out of bounds or not a multiple of the tick spacing.add_liquidity,add_liquidity_by_weightandremove_liquidity:liquiditiesis empty, the number of set bits inbitmapdiffers from its length, or a bit selects a slot beyond the position’s slot count.add_liquidity_imbalance: neithermax_amount_xnormax_amount_yis set,indexis not a slot of the position, orsqrt_price_slippagehas a minimum below the lowest price, a maximum above the highest price or a minimum above the maximum.remove_liquidity_by_bps:bpsis 0 or above 10000,bitmapselects no slot or a slot beyond the slot count, or every selected slot rounds down to zero liquidity so there is nothing to withdraw.remove_position:bitmapselects no slot, a slot beyond the slot count, or every slot of the position.refresh_fees_and_rewards:bitmapselects no slot or a slot beyond the slot count.lock_permanent_positionandlock_vesting_position:bpsis 0 or above 10000.lock_vesting_positionalso rejects acliff_pointin the past, a schedule with neither a cliff unlock nor periods, a schedule that sets some but not all ofperiod_frequency,bps_per_periodandnumber_of_period, a total release (cliff_unlock_bpsplusbps_per_periodtimesnumber_of_period) other than 10000, and a schedule that ends more than 10 years ahead.open_limit_order:ticksis empty or has more than 25 entries, an amount is 0, tick ids are not strictly ascending or not usable,relative_tickbounds are not multiples of the tick spacing or the minimum is above the maximum, an ask order’s lowest tick is not above the current tick id, a bid order’s highest tick is above the current tick id, or the tick already holds pending orders on the other side.cancel_limit_order:tick_idsis empty or not strictly ascending.set_reward_emission:emission_per_secondis 0,open_timeis in the past or more than 30 days ahead, the window is shorter than 1 day or longer than 1 year, or the total reward rounds to 0.update_reward_authority: the new authority equals the current one.- Fix: Check each argument against the constants on the Accounts page. The TypeScript SDK builders reject most of these arguments before sending and name the argument in the message.
- Pool creation (
-
AmountIsZero(6039)swapwith aninput_amountof 0.add_liquidity_imbalancewith amax_amount_xormax_amount_yof 0, or with amounts that add no liquidity because the slot’s range has no room for the token side provided at the current price (token X into a range below the price, token Y into a range above it).- Fix: Pass non-zero amounts and, for an imbalanced deposit, provide the token the range holds at the current price.
-
UndeterminedError(6024)- An internal consistency check fails: a tick array has no free tick slot while ticks are added, a limit order’s age is ahead of its tick, a position’s vesting state cannot be read, or a fee period does not fit its type.
- Fix: No argument controls these checks. Report the transaction with the pool and account addresses.
Swap
-
ExceededSlippage(6019)swap: the output after the output mint’s Token 2022 transfer fee is belowminimum_output_amount.remove_liquidity,remove_liquidity_by_bps,claim_fee,claim_reward,claim_partner_fee,claim_protocol_fee2,withdraw_ineligible_rewardsandcancel_limit_order: the amount received after transfer fee is below the minimum argument (min_amount_x,min_amount_y,min_amount). A minimum of 0 skips the check.add_liquidity,add_liquidity_by_weight,add_liquidity_imbalance,open_limit_orderandset_reward_emission: the amount to pay, transfer fee included, is above the maximum argument (max_amount_x,max_amount_y,max_amount).add_liquidity_imbalance: the pool price is outsidesqrt_price_slippage, or the liquidity derived from the maximum amounts is belowmin_liquidity.open_limit_orderwithrelative_tick: the current tick id, aligned to the tick spacing, is outside the minimum and maximum tick ids.- Fix: Quote again and widen the bound, or send the transaction sooner.
-
NotConsumingFullAmountIn(6020)swapis exact-in, and the tick arrays passed ran out of liquidity before the wholeinput_amountwas used. The pool may hold liquidity in further tick arrays that were not passed or were passed out of swap direction order.- Fix: Pass the tick arrays of a quote whose
amountLeftis zero, in swap direction order, or lower the input amount.
-
InvalidActivationAccess(6040)swap: swaps are disabled inpool_status(bit 0), or the pool has activation rules and the signer is not the whitelisted swap address while an activation slot does not yet allow swaps.open_position,expand_position,add_liquidity,add_liquidity_by_weight,add_liquidity_imbalanceandopen_limit_order: adding liquidity is disabled inpool_status(bit 1), or the activation rules do not yet allow it. The address checked is the NFT owner, or theowneraccount for the two open instructions.remove_liquidity,remove_liquidity_by_bps,remove_positionandcancel_limit_order: the activation rules do not yet allow removing liquidity for the NFT owner.pool_statuscannot block removal.- Pool creation with the ActivationAccess extension: an
activation_modebyte other than 0, 1 or 2. - Fix: Wait for the activation point, or use the whitelisted wallet.
Pool Creation and Configs
-
InvalidActivationType(6035)initialize_pool_with_dynamic_configorinitialize_launch_poolwith anactivation_typeother than 0 (Slot) or 1 (Timestamp).- Fix: Use 0 or 1.
-
InvalidBaseFeeMode(6036)base_fee_modein the fee settings ofinitialize_pool_with_dynamic_config,initialize_launch_poolorcreate_static_configis not 0 to 4.- Fix: Use one of the five modes: 0 Fixed, 1 TimeSchedulerLinear, 2 TimeSchedulerExponential, 3 MarketCapSchedulerLinear, 4 MarketCapSchedulerExponential.
-
InvalidPoolCreatorAuthority(6046)- Pool creation with a config whose
pool_creator_authoritydiffers from thepool_creator_authorityaccount passed. initialize_pool_with_static_configwith a non-public config (authority is not the default key) and thepool_creator_authorityaccount did not sign.- Fix: Pass the config’s pool creator authority, and have it sign unless the config is public.
- Pool creation with a config whose
-
InvalidTokenOwnerProof(6007)initialize_launch_poolwith auser_token_xoruser_token_ybalance of 0. The payer must hold both tokens.- Fix: Fund the payer’s token accounts for both mints before creating the launch pool.
Tick Arrays and Bitmap
-
InvalidTickArray(6015)- Any instruction that takes tick arrays: a tick array account passed belongs to a different pool.
open_position,expand_position,open_limit_order,remove_position,close_positionandclose_limit_order: fewer tick array accounts than the ticks need, accounts out of ascending index order (open_limit_orderwithrelative_tickaccepts any order), an address that is not the tick array for the index expected at that position, or an existing array whose stored pool or index does not match.- Fix: Derive each tick array with
deriveTickArray(pool, index)and pass them in the order the Instructions page lists.
-
CannotFindTickFromId(6016)add_liquidity,add_liquidity_by_weight,add_liquidity_imbalance,remove_liquidityandremove_liquidity_by_bps: none of the tick arrays passed holds the lower or upper tick of a selected slot.refresh_fees_and_rewards: the same, for the slots inbitmap.cancel_limit_order: none of the tick arrays passed holds a listed tick.remove_position,close_positionandclose_limit_order: a tick array passed does not hold a tick being released.- Fix: Pass the tick arrays that hold the lower and upper tick of every selected slot, or every tick of the limit order.
-
TickArrayBitmapExtensionAccountIsNotProvided(6021)- Liquidity changes or limit order calls that switch a tick array outside indexes -512 to 511 between empty and holding liquidity, with no bitmap extension account passed. A swap in that situation fails with
BitmapExtensionAccountIsNotProvided(6044) instead. - Pool creation with an initial tick whose tick array index is outside -512 to 511 and no bitmap extension account passed.
- Fix: Pass
deriveTickArrayBitmapExtension(pool), creating it first withinitialize_tick_bitmap_extensionif needed.
- Liquidity changes or limit order calls that switch a tick array outside indexes -512 to 511 between empty and holding liquidity, with no bitmap extension account passed. A swap in that situation fails with
-
BitmapExtensionAccountIsNotProvided(6044)swapon a pool that has a bitmap extension: the search for the next tick array with liquidity leaves the inline bitmap and the extension account is not passed.- Fix: Pass
deriveTickArrayBitmapExtension(pool)on every swap of a pool that has one.
-
ReallocExceedMaxLengthPerInstruction(6009)open_positionorexpand_positionadds more than 64 new ticks to one tick array (more than 53 on LiquidityMining pools, where ticks are larger), or more than 63 when the instruction also creates the array on a pool without LiquidityMining. One instruction can grow an account by at most 10,240 bytes.open_limit_orderstays below the limit because an order has at most 25 ticks.- The same check guards the growth of the position array and the oracle, but their size limits (45 slots, 500 observations) keep them below it.
- Fix: Open the position with fewer ranges, then add the rest with
expand_position.
-
UnmatchedTickIndex(6008)- Defined in the IDL but not returned by any instruction in release 0.1.0.
- Fix: Nothing to fix.
-
TickIdIsOutOfBound(6010)- Defined in the IDL but not returned by any instruction in release 0.1.0.
- Fix: Nothing to fix. Tick ids outside the bounds are rejected with
InvalidParameters.
-
CannotModifyAccount(6045)- An account resize that is meant to shrink would grow the account. The instructions in this release only shrink accounts to a smaller size, so integrators should not see this error.
- Fix: Report the transaction if it appears.
Positions and Liquidity
-
LiquidityIsZero(6023)swap: no tick array with liquidity exists in the swap direction from the current tick.add_liquidity,add_liquidity_by_weight,remove_liquidity: an entry ofliquiditiesis 0 (including a weight of 0).add_liquidity_imbalance: the liquidity derived from the amounts is 0.lock_permanent_position,lock_vesting_position: no range slot has unlocked liquidity to lock.- Fix: Check pool liquidity in the swap direction, and pass non-zero liquidity amounts on positions that hold unlocked liquidity.
-
LiquidityIsTooHigh(6022)add_liquidity,add_liquidity_by_weight,remove_liquidity: an entry ofliquiditiesis above the largest signed 128-bit integer.- Adding liquidity would push the total liquidity of a tick above the per-tick cap, which is the largest
u128divided by the number of usable ticks at the pool’s tick spacing. - Fix: Add less liquidity per range.
-
InsufficientLiquidity(6043)- Defined in the IDL but not returned by any instruction in release 0.1.0.
- Fix: Nothing to fix. Removing more than a slot holds fails with
MathOverflow.
-
PositionIsNotEmpty(6033)close_position: a range slot still has liquidity (unlocked, locked or vesting), pending fees, or pending rewards on a LiquidityMining pool.remove_position: a selected slot is not empty in the same way.- Fix: Remove liquidity, then claim fees and rewards, before closing the position or removing the slot. Permanently locked liquidity cannot be removed, so such a position cannot be closed.
-
InvalidLayoutVersion(6050)add_liquidity,add_liquidity_by_weight,add_liquidity_imbalance,remove_liquidity,remove_liquidity_by_bps,remove_position,lock_permanent_positionorlock_vesting_positionwith anexpected_layout_versionthat differs from the position’slayout_version. The version changes on everyexpand_positionandremove_position.- Fix: Read the position again and pass the current version, or pass
None.
Locks and Vesting
Locking also fails withInvalidParameters for a bad bps or schedule, LiquidityIsZero when there is no unlocked liquidity, and InvalidLayoutVersion for a stale layout version. Only the NFT owner can lock, so a delegate signing lock_permanent_position or lock_vesting_position is stopped by an Anchor constraint (see Anchor Framework Errors).
PositionAlreadyHadVesting(6042)lock_vesting_positionon a position that already has a vesting schedule. A position can have one in its lifetime, even after the schedule has fully released.- Fix: Lock from a different position.
Limit Orders
-
CannotFindLimitOrderByTickId(6025)cancel_limit_orderlists a tick id that is not one of the ticks of the limit order.- Fix: Use the tick ids stored on the limit order.
-
CancelNonEmptyLimitOrder(6026)cancel_limit_orderlists a tick that was already canceled. The message reads “Cancel on empty limit order”, which describes the tick being empty.- Fix: Read the limit order and cancel only ticks that still hold an order.
-
LimitOrderIsNotEmpty(6034)close_limit_orderwhile at least one tick of the order is not canceled.- Fix: Cancel every tick, then close.
Rewards
All reward instructions work on pools with the LiquidityMining extension and a reward index of 0 or 1.-
InvalidRewardIndex(6014)claim_reward,initialize_reward,set_reward_emission,update_reward_authorityorwithdraw_ineligible_rewardswith an index of 2 or above.- Fix: Use reward index 0 or 1.
-
RewardUninitialized(6029)claim_reward,set_reward_emission,update_reward_authorityorwithdraw_ineligible_rewardson a reward slot that has no mint yet.- Fix: Call
initialize_rewardfor the slot first.
-
InvalidRewardMint(6030)claim_reward,set_reward_emissionorwithdraw_ineligible_rewardswith areward_mintthat differs from the mint stored in the slot.- Fix: Pass the mint of the slot.
-
InvalidRewardVault(6031)claim_reward,set_reward_emissionorwithdraw_ineligible_rewardswith areward_vaultthat differs from the vault stored in the slot.- Fix: Pass
deriveRewardVault(pool, index).
-
InvalidRewardState(6041)initialize_rewardon a slot that is already initialized.set_reward_emissionwhile the previous emission is still running, or after it ended but the reward emitted during empty liquidity has not been withdrawn.withdraw_ineligible_rewardsbefore an emission has ended, or on a slot that never had an emission.- Fix: Wait for the emission to end and call
withdraw_ineligible_rewardsbefore setting a new emission.
-
InvalidPoolType(6027)claim_reward,initialize_reward,set_reward_emission,update_reward_authorityorwithdraw_ineligible_rewardson a pool without the LiquidityMining extension.- Fix: Use a pool created with the LiquidityMining extension.
-
IdenticalFunder(6032)- Defined in the IDL but not returned by any instruction in release 0.1.0.
- Fix: Nothing to fix.
Tokens and Token 2022
-
UnsupportNativeMintToken2022(6004)- Pool creation with the Token 2022 native mint as token X or token Y, or
initialize_rewardwith it as the reward mint. This check applies even when a config skips other mint checks. - Fix: Use wrapped SOL from the Token program instead.
- Pool creation with the Token 2022 native mint as token X or token Y, or
-
InvalidTokenBadge(6005)- A token badge account is passed whose stored mint is not the mint it is meant for, in pool creation or
initialize_reward. CollectFeeMode.OnlyYpool creation where token Y is not wrapped SOL or USDC and no badge, or a badge for another mint, is passed astoken_badge_y.- Fix: Pass
deriveTokenBadge(mint)for the right mint.
- A token badge account is passed whose stored mint is not the mint it is meant for, in pool creation or
-
UnsupportedMint(6006)- No token badge is passed and the mint is not wrapped SOL or USDC, and it is a Token 2022 mint with an extension other than transfer fee, metadata pointer or token metadata, or with a transfer hook that has a program or authority set.
- No token badge is passed and a reward mint set up by the pool creator (slot 0) has a freeze authority.
- Fix: Pass a token badge from the access registry, or use a mint without the extension.
-
MissingRemainingAccountForTransferHook(6017)- A transfer in the instruction involves a mint with a transfer hook program and the matching transfer hook slice of
remaining_accounts_infois missing or has no accounts. - Fix: Pass the extra accounts of the hook program in a slice of the type for that leg. The SDK builders resolve them.
- A transfer in the instruction involves a mint with a transfer hook program and the matching transfer hook slice of
-
NoTransferHookProgram(6018)- A transfer hook slice with accounts is passed for a mint that has no transfer hook program.
- Fix: Leave the slice out, or pass an empty list, for mints without a hook.
-
InsufficientRemainingAccounts(6011)- The lengths in
remaining_accounts_infoadd up to more accounts than the instruction received. open_limit_orderwithrelative_tick: a tick array needed by one of the order’s ticks is not among the remaining accounts.- Fix: Pass every account the slices declare, followed by the tick arrays.
- The lengths in
-
InvalidRemainingAccountSlice(6012)- A slice has an
accounts_typethat the instruction does not accept.swapandcancel_limit_orderacceptTransferHookX,TransferHookYandTransferHookReferral.add_liquidity,add_liquidity_by_weight,add_liquidity_imbalance,remove_liquidity,remove_liquidity_by_bps,claim_fee,claim_partner_feeandclaim_protocol_fee2acceptTransferHookXandTransferHookY.claim_reward,set_reward_emissionandwithdraw_ineligible_rewardsacceptTransferHookReward.open_limit_orderacceptsTransferHookXfor an ask order andTransferHookYfor a bid order. - Fix: Use only the slice types the instruction accepts.
- A slice has an
-
DuplicatedRemainingAccountTypes(6013)- Two slices in
remaining_accounts_infohave the sameaccounts_type. - Fix: Use each slice type at most once.
- Two slices in
-
IncorrectATA(6049)- A delegate signed
remove_liquidity,remove_liquidity_by_bps,claim_fee,claim_rewardorcancel_limit_orderand a destination token account is not the owner’s associated token account for that mint and token program. - Fix: Pay into the owner’s associated token account, or sign as the owner.
- A delegate signed
Permissions and Operators
-
InvalidAdmin(6002)create_operator_accountorclose_operator_accountsigned by an address that is not the program admin.- Fix: These instructions are for the program admin only.
-
InvalidPermission(6003)create_static_config,create_dynamic_config,close_config,set_pool_status,update_partner_fee: the operator account is not for the signer, or its permissions do not include the one the instruction needs.create_operator_account:permissionis 0 or has a bit beyond the six defined operator permissions.update_position_delegate_permissionorupdate_limit_order_delegate_permission:permissionhas a bit beyond those defined (bits 0 to 4 for positions, bit 0 for limit orders).- A delegate calls an instruction for which the NFT’s permission bitmask does not grant the permission (AddLiquidity, RemoveLiquidity, ClaimFee, ClaimReward, UpdatePositionRange or CancelLimitOrder).
remove_positionsigned by a delegate whoserent_receiveris not the NFT owner.initialize_reward: an operator account is passed but is not for the signer or lacks InitializeReward, or no operator is passed and the signer is not the pool creator initializing slot 0.update_reward_authority: the signer is neither the pool creator for slot 0 nor an operator for the signer with UpdateRewardAuthority.set_reward_emissionorwithdraw_ineligible_rewards: the signing authority is not the authority of the slot.- Fix: Sign with the right account and check the operator or delegate permission bits.
-
InvalidAuthority(6047)- A position or limit order instruction signed by an address that is neither the NFT owner nor the delegate approved on the NFT token account.
claim_partner_feesigned by an address that is not the pool’s partner.- Fix: Sign as the NFT owner, an approved delegate, or the pool partner.
-
MissingOperatorAccount(6028)update_reward_authoritysigned by an address that is not the pool creator of slot 0, with nooperatoraccount passed.- Fix: Pass the operator account of the signer.
-
DelegatedAmountNonZero(6048)- A delegate acts on an NFT token account whose approval is for an amount above 0.
- Fix: Approve the delegate with an amount of 0 (Token 2022
approve).
Accounts
InvalidAccount(6038)claim_protocol_fee2with a receiver token account whose mint is neither of the pool’s mints, or which is not owned by the token program of that mint. The TypeScript SDK also throws it fromquoteExactInfor a bitmap extension of another pool.- Fix: Pass a token account of one of the pool’s mints under the matching token program.
Anchor Framework Errors
Account constraints run before the instruction logic, so a wrong or missing account fails with an Anchor framework error instead of a program error. These are the ones this program can return. In the log, the line that starts withProgram log: AnchorError gives the error name and number, and for constraint errors it also names the account from the IDL that failed.
SDK Error Codes
The TypeScript SDK exportsPoolErrorCode with the same numbering, so the custom code of a failed transaction maps to the same name. PoolError is thrown for inputs the builders reject before sending, and its message names the argument that failed.
Errors the SDK Can Throw Before Sending
The builders, the quote and the helpers throwPoolError for input they can check without reading program state. The codes below match the program’s. Most are raised from the arguments and from the accounts you pass in, not from live pool state; getClaimableFees and compoundFees also read the position and its tick arrays. An ordinary transaction can still fail with an error that is not on this list.
Some failures are plain
Errors, not PoolErrors: a missing account, an account that does not decode, or a missing sysvar or mint during a fetch. ExceededSlippage and NotConsumingFullAmountIn only come from the program, because they depend on pool state when the transaction lands.
Mapping a Failed Transaction to a Name
A failed transaction shows the program error in two forms. The log readscustom program error: 0x1784, and the transaction error reads InstructionError: [0, { Custom: 6020 }]. They are the same number, once in hex and once in decimal. Program errors run from 6000 (0x1770) to 6050 (0x17a2), so subtract 6000 to get the position in the Error Codes table, or look the decimal value up in PoolErrorCode. A code below 6000 is not a program error: 2000 to 2999 (0x7d0 to 0xbb7) are Anchor constraint errors and 3000 to 3999 (0xbb8 to 0xf9f) are Anchor account errors, listed in Anchor Framework Errors.

