Skip to main content
The program returns Anchor custom errors, numbered from 6000.
A failed transaction log shows custom program error: 0x1784. Convert the hex value to decimal to find the error: 0x1784 is 6020, NotConsumingFullAmountIn.

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_liquidity asks for more liquidity from a range slot than the slot holds unlocked. The program has an InsufficientLiquidity error, but release 0.1.0 never returns it, and this one fires instead.
    • add_liquidity_by_weight has a multiplier times a weight that does not fit in u128.
    • set_reward_emission has end_time below the open time.
    • Fix: Check amounts against the position state before sending, and use smaller multiplier values and liquidity amounts.
  • TypeCastFailed (6001)
    • A byte that must be an enum value is out of range. collect_fee_mode must be 0 or 1 in initialize_pool_with_dynamic_config, initialize_launch_pool and create_static_config, and activation_type must be 0 or 1 in create_static_config.
    • A value does not fit its target type during a calculation, such as the liquidity derived by add_liquidity_imbalance exceeding u128 or a scheduled base fee result exceeding u64.
    • Fix: Send valid enum values and keep prices, liquidity and amounts inside the documented ranges.
  • InvalidParameters (6037)
    • Pool creation (initialize_pool_with_dynamic_config, initialize_launch_pool) and create_static_config: tick_spacing is 0 or above 256, or extensions has a bit other than the two defined. create_static_config also rejects the ActivationAccess bit.
    • Pool creation: initial_sqrt_price is 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_factor or number_of_period; a market cap scheduler with a zero reduction_factor, sqrt_price_step_bps, scheduler_expiration_duration or number_of_period; non-zero padding bytes in data.
    • Dynamic fee settings: max_volatility_accumulator or variable_fee_control above 16777215, filter_period of 0 or not below decay_period, decay_period above 3600, reduction_factor of 0 or above 10000, min_delta_tick_for_significant_swap of 0, or a highest variable fee above 99 percent.
    • ActivationAccess pools: pool_activation missing, 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-default whitelisted_add_liquidity, with is_reach_target set, with target_increase_bps of 10000 or less, or with a target price above the highest usable tick; TimeBased points in the past or more than 30 days ahead, or activation_point different from swap_point). Without a TimeBased slot, activation_point must be the current slot or timestamp. Pools without the extension must omit both activation_point and pool_activation.
    • create_dynamic_config: permission above 1, partner_fee_bps above 5000, or pool_creator_authority equal to the default key.
    • close_config: both or neither of the static and dynamic config accounts are passed.
    • set_pool_status: status above 3, or equal to the current status. update_partner_fee: partner_fee_bps above 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_add is 0 or the new length would exceed 500.
    • open_position and expand_position: tick_ranges is empty, the position would exceed 45 range slots, a range has tick_lower_id not below tick_upper_id, or an id is out of bounds or not a multiple of the tick spacing.
    • add_liquidity, add_liquidity_by_weight and remove_liquidity: liquidities is empty, the number of set bits in bitmap differs from its length, or a bit selects a slot beyond the position’s slot count.
    • add_liquidity_imbalance: neither max_amount_x nor max_amount_y is set, index is not a slot of the position, or sqrt_price_slippage has a minimum below the lowest price, a maximum above the highest price or a minimum above the maximum.
    • remove_liquidity_by_bps: bps is 0 or above 10000, bitmap selects 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: bitmap selects no slot, a slot beyond the slot count, or every slot of the position.
    • refresh_fees_and_rewards: bitmap selects no slot or a slot beyond the slot count.
    • lock_permanent_position and lock_vesting_position: bps is 0 or above 10000. lock_vesting_position also rejects a cliff_point in the past, a schedule with neither a cliff unlock nor periods, a schedule that sets some but not all of period_frequency, bps_per_period and number_of_period, a total release (cliff_unlock_bps plus bps_per_period times number_of_period) other than 10000, and a schedule that ends more than 10 years ahead.
    • open_limit_order: ticks is empty or has more than 25 entries, an amount is 0, tick ids are not strictly ascending or not usable, relative_tick bounds 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_ids is empty or not strictly ascending.
    • set_reward_emission: emission_per_second is 0, open_time is 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.
  • AmountIsZero (6039)
    • swap with an input_amount of 0.
    • add_liquidity_imbalance with a max_amount_x or max_amount_y of 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 below minimum_output_amount.
    • remove_liquidity, remove_liquidity_by_bps, claim_fee, claim_reward, claim_partner_fee, claim_protocol_fee2, withdraw_ineligible_rewards and cancel_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_order and set_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 outside sqrt_price_slippage, or the liquidity derived from the maximum amounts is below min_liquidity.
    • open_limit_order with relative_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)
    • swap is exact-in, and the tick arrays passed ran out of liquidity before the whole input_amount was 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 amountLeft is zero, in swap direction order, or lower the input amount.
  • InvalidActivationAccess (6040)
    • swap: swaps are disabled in pool_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_imbalance and open_limit_order: adding liquidity is disabled in pool_status (bit 1), or the activation rules do not yet allow it. The address checked is the NFT owner, or the owner account for the two open instructions.
    • remove_liquidity, remove_liquidity_by_bps, remove_position and cancel_limit_order: the activation rules do not yet allow removing liquidity for the NFT owner. pool_status cannot block removal.
    • Pool creation with the ActivationAccess extension: an activation_mode byte 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_config or initialize_launch_pool with an activation_type other than 0 (Slot) or 1 (Timestamp).
    • Fix: Use 0 or 1.
  • InvalidBaseFeeMode (6036)
    • base_fee_mode in the fee settings of initialize_pool_with_dynamic_config, initialize_launch_pool or create_static_config is 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_authority differs from the pool_creator_authority account passed.
    • initialize_pool_with_static_config with a non-public config (authority is not the default key) and the pool_creator_authority account did not sign.
    • Fix: Pass the config’s pool creator authority, and have it sign unless the config is public.
  • InvalidTokenOwnerProof (6007)
    • initialize_launch_pool with a user_token_x or user_token_y balance 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_position and close_limit_order: fewer tick array accounts than the ticks need, accounts out of ascending index order (open_limit_order with relative_tick accepts 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_liquidity and remove_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 in bitmap.
    • cancel_limit_order: none of the tick arrays passed holds a listed tick.
    • remove_position, close_position and close_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 with initialize_tick_bitmap_extension if needed.
  • BitmapExtensionAccountIsNotProvided (6044)
    • swap on 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_position or expand_position adds 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_order stays 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 of liquidities is 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 of liquidities is 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 u128 divided 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_position or lock_vesting_position with an expected_layout_version that differs from the position’s layout_version. The version changes on every expand_position and remove_position.
    • Fix: Read the position again and pass the current version, or pass None.

Locks and Vesting

Locking also fails with InvalidParameters 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_position on 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_order lists 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_order lists 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_order while 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_authority or withdraw_ineligible_rewards with an index of 2 or above.
    • Fix: Use reward index 0 or 1.
  • RewardUninitialized (6029)
    • claim_reward, set_reward_emission, update_reward_authority or withdraw_ineligible_rewards on a reward slot that has no mint yet.
    • Fix: Call initialize_reward for the slot first.
  • InvalidRewardMint (6030)
    • claim_reward, set_reward_emission or withdraw_ineligible_rewards with a reward_mint that differs from the mint stored in the slot.
    • Fix: Pass the mint of the slot.
  • InvalidRewardVault (6031)
    • claim_reward, set_reward_emission or withdraw_ineligible_rewards with a reward_vault that differs from the vault stored in the slot.
    • Fix: Pass deriveRewardVault(pool, index).
  • InvalidRewardState (6041)
    • initialize_reward on a slot that is already initialized.
    • set_reward_emission while the previous emission is still running, or after it ended but the reward emitted during empty liquidity has not been withdrawn.
    • withdraw_ineligible_rewards before an emission has ended, or on a slot that never had an emission.
    • Fix: Wait for the emission to end and call withdraw_ineligible_rewards before setting a new emission.
  • InvalidPoolType (6027)
    • claim_reward, initialize_reward, set_reward_emission, update_reward_authority or withdraw_ineligible_rewards on 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_reward with 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.
  • 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.OnlyY pool creation where token Y is not wrapped SOL or USDC and no badge, or a badge for another mint, is passed as token_badge_y.
    • Fix: Pass deriveTokenBadge(mint) for the right mint.
  • 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_info is 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.
  • 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_info add up to more accounts than the instruction received.
    • open_limit_order with relative_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.
  • InvalidRemainingAccountSlice (6012)
    • A slice has an accounts_type that the instruction does not accept. swap and cancel_limit_order accept TransferHookX, TransferHookY and TransferHookReferral. add_liquidity, add_liquidity_by_weight, add_liquidity_imbalance, remove_liquidity, remove_liquidity_by_bps, claim_fee, claim_partner_fee and claim_protocol_fee2 accept TransferHookX and TransferHookY. claim_reward, set_reward_emission and withdraw_ineligible_rewards accept TransferHookReward. open_limit_order accepts TransferHookX for an ask order and TransferHookY for a bid order.
    • Fix: Use only the slice types the instruction accepts.
  • DuplicatedRemainingAccountTypes (6013)
    • Two slices in remaining_accounts_info have the same accounts_type.
    • Fix: Use each slice type at most once.
  • IncorrectATA (6049)
    • A delegate signed remove_liquidity, remove_liquidity_by_bps, claim_fee, claim_reward or cancel_limit_order and 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.

Permissions and Operators

  • InvalidAdmin (6002)
    • create_operator_account or close_operator_account signed 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: permission is 0 or has a bit beyond the six defined operator permissions.
    • update_position_delegate_permission or update_limit_order_delegate_permission: permission has 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_position signed by a delegate whose rent_receiver is 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_emission or withdraw_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_fee signed 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_authority signed by an address that is not the pool creator of slot 0, with no operator account 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_fee2 with 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 from quoteExactIn for 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 with Program 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 exports PoolErrorCode 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.
See the TypeScript SDK reference for the full list of builders that throw it.

Errors the SDK Can Throw Before Sending

The builders, the quote and the helpers throw PoolError 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 reads custom 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.