Skip to content

Error Codes

Anchor error codes from high-market-parlay, in declaration order (Anchor assigns 6000 + index).

CodeNameWhen
6000Pausedcreate_parlay while config.is_paused == true
6001UnauthorizedSigner isn’t the admin, an account ownership check failed, or a void_parlay user mismatch
6002TooFewLegslegs.len() < 2
6003TooManyLegslegs.len() > config.max_legs
6004DuplicateMarketTwo legs reference the same market_id
6005SameEventCorrelationTwo legs reference markets sharing an event_id
6006InvalidEventLinkA MarketEventLink doesn’t match the derived PDA, has a wrong discriminator, or its embedded market_id differs
6007RemainingAccountsLengthMismatchNot exactly 2 × legs.len() remaining accounts
6008StakeTooLowstake < config.min_stake
6009StakeTooHighstake > config.max_stake
6010PayoutExceedsMaxpotential_payout > config.max_payout
6011ExposureLimitExceededtotal_exposure + payout > 0.8 × (vault.amount + stake)
6012MarketNotOpenA leg’s market isn’t Open at create time
6013MarketNotResolvedsettle_leg before the market is Resolved or Cancelled
6014ProbabilityOutOfRangeA leg falls outside the configured [prob_floor_bps, prob_ceiling_bps] band
6015MarketTooNewMarket younger than config.min_market_age_secs
6016MarketTooShallowAMM liquidity b below config.min_market_b
6017MarketTooIlliquidtotal_volume below config.min_market_volume
6018InvalidProbabilityBandAdmin band violates HARD_PROB_FLOOR ≤ floor < ceiling ≤ HARD_PROB_CEILING
6019InvalidMarketAgemin_market_age_secs < TWAP_WINDOW_SECS
6020InvalidAmmProgramIdinitialize called with anything but the compiled-in EXPECTED_AMM_PROGRAM_ID
6021MarketExpiredA leg’s market is past its end_time
6022FreezableCollateralMintThe collateral mint retains a freeze authority (Circle USDC is the one exception)
6023CollateralMintMismatchA leg settles in a different collateral mint than the parlay vault
6024ParlayHasResolvedLegsvoid_parlay on an Active slip that already has a resolved leg
6025NoPendingAdminaccept_admin with nothing queued
6026ClaimWindowNotElapsedvoid_parlay on a Won slip still inside its claim window
6027ParlayNotVoidablevoid_parlay on an already-terminal slip
6028InvalidClaimDeadlineclaim_deadline_secs outside [1 hour, ~3 years]
6029UseUpdateTreasuryInstructionTreasury passed to update_config instead of update_treasury
6030InvalidAdminPubkeyAdmin set to the all-zeros / system program address
6031ParlayNotWonclaim_parlay on a slip that is neither Won nor Voided
6032ParlayNotActivesettle_leg on a non-Active slip
6033LegNotPendingsettle_leg on an already-terminal leg
6034InvalidLegIndexleg_index >= parlay.legs.len()
6035MarketAddressMismatchThe market account doesn’t match leg.market_address
6036InvalidMarketOwnerA market or link account isn’t owned by config.amm_program_id
6037InvalidMarketAccountDiscriminator or layout check failed deserialising as Market
6038InsufficientVaultFundsclaim_parlay or withdraw_vault would over-draw
6039MathOverflowChecked arithmetic overflowed
6040LmsrPriceFailedLMSR price_yes returned None
6041CombinedProbabilityZeroThe combined probability truncated to zero
6042SlippageExceededpotential_payout < min_payout
6043InvalidAmountseed_vault / propose_withdraw_vault with amount == 0
6044InvalidFeefee_bps > MAX_FEE_BPS (1000 = 10%)
6045InvalidMaxLegsmax_legs outside [2, 10]
6046InvalidStakeBoundsmin_stake == 0 or min_stake > max_stake
6047InvalidMaxPayoutmax_payout == 0
6048TwapWindowTooShortNot a full averaging window of price history
6049TwapTooStaleThe market hasn’t traded recently enough to price
6050TimelockNotElapsedaccept_admin or withdraw_vault before the 48-hour delay
6051NoPendingWithdrawalwithdraw_vault / cancel_withdraw_vault with nothing queued
6052WithdrawalMismatchwithdraw_vault amount or destination differs from what was proposed
SourceCodes
Slip construction6002, 6003, 6004, 6005, 6006, 6007, 6008, 6009, 6042
Market quality6012, 6014, 6015, 6016, 6017, 6021, 6023, 6048, 6049
Cross-program account checks6006, 6020, 6036, 6037
Vault solvency6010, 6011, 6038
State-machine guards6013, 6024, 6026, 6027, 6031, 6032, 6033, 6034, 6035
Admin config writes6018, 6019, 6022, 6028, 6029, 6030, 6044, 6045, 6046, 6047
Timelocks6025, 6050, 6051, 6052
Genuine overflow6039, 6040, 6041
Authorisation6001
BehaviourCodes
Harmless — already done6033 (LegNotPending)
Retry with different input6008, 6009, 6010, 6011, 6042 — adjust stake or min_payout
Wait6013 (market not terminal), 6050 (timelock running)
Don’t retry — the slip is invalid6002, 6003, 6004, 6005, 6006, 6012, 6014, 6015, 6016, 6017, 6021, 6023
Escalate6020, 6036, 6037, 6039, 6040, 6041 — a bug or a bad account

The user_seq collision is not an Anchor error — it surfaces as Solana’s “account already in use,” because the Parlay PDA is seeded on (user, user_seq). Increment user_seq and retry; the webapp retries up to four times.

What the webapp shows:

ErrorMessage
ExposureLimitExceededVault exposure limit exceeded — reduce stake
PayoutExceedsMaxPotential payout exceeds the maximum
StakeTooLow / StakeTooHighStake below/above allowed range
MarketExpiredA selected market has expired
MarketTooNewA market is too new for parlays
MarketTooShallow / MarketTooIlliquidA market has too little liquidity
TwapTooStale / TwapWindowTooShortA market hasn’t traded recently enough to price
ProbabilityOutOfRangeA selected outcome’s odds are outside the allowed band
SameEventCorrelationTwo legs are from the same event
DuplicateMarketSame market added twice
CollateralMintMismatchA market uses an unsupported collateral token

The order manager returns success: false with a human-readable errorMsg rather than numeric codes.

ReasonCauseFix
Invalid signatureOrder-hash layout mismatchCheck field order and LE encoding byte for byte
Unsupported signature typesignatureType != 0Only EOA settles on-chain
Signer mismatchsigner != makerThey must be the same key
Non-public takertaker isn’t the zero addressBilateral orders aren’t supported
Invalid noncenonce != "0"There is no on-chain nonce account
Tick-size violationPrice off the gridRound the amounts so the ratio lands on a tick
Fee rate too lowA marketable order below the taker feeSet the taker rate
Insufficient balanceATA short, or reserved by earlier ordersFund or cancel
Book not foundMarket not in the catalogue, or not readyCheck GET /v1/markets
Duplicate orderThe hash already existsChange the salt
Market not readyis_market_ready failedWait
Expiredexpiration in the past—

A missing delegate allowance is a warning, not a rejection. The order rests and settlement fails on-chain. Set it first.

not_canceled maps each order hash to a reason — already filled, already cancelled, or not owned by you. Cancels aren’t atomic across a batch; always read both fields.

StatusMeaning
MINEDThe transaction landed, not yet final
CONFIRMEDFinalized on Solana — the settlement point
FAILEDSettlement failed; affected orders reconciled

On FAILED the executor invalidates the resting orders involved via the internal OrderSizeUpdate route. Your order disappears and the fill never happened.

ConditionBehaviour
DuplicateTradeThe trade key was already seen — rejected, not retried
Out of gas (CU ≥ 95% of limit)Retried with CU ×2, fee ×2, up to RETRIES_LIMIT
Stuck past STUCK_TX_MAX_IDLE_TIMERe-executed through the same path
Final failureUpdateTrade(FAILED) + order reconciliation

Standard DRF conventions.

StatusMeaning
400Validation failure; body carries field errors
401Missing or invalid JWT
403Authenticated but not permitted (superuser routes, webhook secret mismatch)
404Not found — or not yours; the two are indistinguishable by design
502Upstream RPC failure (e.g. vault/sync/)
503A required secret isn’t configured (webhook routes)

The 404-for-unauthorised choice is deliberate: parlay ids must not be probeable. Don’t interpret it as “deleted.”