PollarPollar

Error Codes

@pollar 0.11.x. This page documents the 0.11 release line, which talks to SDK API v2. The current release is 0.12, documented under Latest. On 0.11.x the ramp methods answer 410 SDK_RAMPS_MOVED_TO_V3: ramps need 0.12. To move, read the 0.11 -> 0.12 upgrade notes.

Pollar surfaces errors in two places: the Server / SDK API (HTTP responses) and the client SDK (method outcomes and reactive state). This page documents both, plus the real error codes.


Error model

Server / SDK API responses

Every API response uses a fixed envelope. Errors are flat — there is no error wrapper and no message/status field in the body (the HTTP status code carries the status):

{
  "code": "INSUFFICIENT_FUNDS_FOR_TRUSTLINE",
  "success": false
}

Some errors include extra fields (e.g. validation issues):

{
  "code": "VALIDATION_ERROR",
  "success": false,
  "details": { "fieldErrors": { "publicKey": ["Must start with G"] } }
}

Successful responses are { "content": <data>, "code": "<SUCCESS_CODE>", "success": true }.

Client SDK

Most @pollar/core methods do not throw on operational failures. Instead they:

  • Return an outcome object — e.g. buildTx, signAndSubmitTx, runTx resolve to { status: 'error', details?, resultCode? } (vs 'built' | 'success' | 'pending').
  • Drive reactive state — tx.step === 'error' carries { phase, details }; auth/balance/history states expose { step: 'error', message }.
const result = await pollar.runTx('payment', { destination, amount, asset });
if (result.status === 'error') {
  console.error(result.details, result.resultCode);
}

The only error that is thrown is PollarFlowError (exported from @pollar/core), raised when a flow method is called out of order (e.g. verifying an OTP code before one was sent). Its code is always 'INVALID_FLOW':

import { PollarFlowError } from '@pollar/core';

try {
  pollar.verifyEmailCode('123456');
} catch (err) {
  if (err instanceof PollarFlowError) {
    // called the wrong step for the current AuthState
  }
}

Auth flow error codes (surfaced on the error AuthState) are exported as AUTH_ERROR_CODES (e.g. SESSION_EXPIRED, EMAIL_CODE_INVALID, WALLET_AUTH_FAILED, PASSKEY_FAILED).


Auth, API keys & access

CodeDescriptionResolution
INVALID_CREDENTIALSMissing or invalid credentialsCheck the credentials you are sending
FORBIDDENAuthenticated but not allowed to perform this actionVerify the key type / permissions
API_KEY_NOT_FOUNDAPI key does not exist or was revokedGenerate a new key from Build → API Keys
API_KEY_EXPIREDAPI key has expiredRotate the key
API_KEY_TYPE_NOT_ALLOWEDPublishable key used on a secret-key route (or vice versa)Use a secret key on the Server API, publishable on the SDK API
ORIGIN_NOT_ALLOWEDRequest origin is not in the app's allowed originsAdd the origin under Build → Domains
REDIRECT_URI_NOT_ALLOWEDOAuth redirect_uri is not in the app's allowed redirect URIsAdd its origin under Build → Domains
APPLICATION_HAS_NO_REDIRECT_URISThe app has no allowed redirect URI registered, so no OAuth login can startRegister the callback under Build → Domains
RATE_LIMITEDToo many requestsBack off and retry

Keys are network-specific by prefix: pub_testnet_ / pub_mainnet_ (publishable) and sec_testnet_ / sec_mainnet_ (secret).


Validation & general

CodeDescriptionResolution
VALIDATION_ERRORMalformed body or failed schema validationCheck the payload against the API reference
INVALID_JSONRequest body is not valid JSONSend a valid JSON body
USER_NOT_FOUNDUser does not exist in your appVerify the externalId / user
APPLICATION_NOT_FOUNDApplication not found for the keyVerify the API key
INTERNAL_SERVER_ERRORUnexpected server errorRetry; contact support if it persists
NOT_IMPLEMENTEDEndpoint exists but is not yet wired upFeature is on the roadmap

Wallet & funding

CodeDescriptionResolution
WALLET_NOT_FOUNDPublic key is not a wallet owned by your appVerify the publicKey
WALLET_NOT_FUNDEDWallet exists but is not yet fundedActivate the wallet before transacting / adding trustlines
WALLET_ALREADY_FUNDEDWallet is already activeSafe to ignore — idempotent activation
WALLET_CREATION_FAILEDFailed to create the wallet on StellarRetry — transient Stellar network issue
FUND_XLM_FAILEDFunding the XLM reserve failedCheck the funding wallet balance, then retry
FRIENDBOT_NOT_AVAILABLETestnet Friendbot funding is unavailableRetry shortly
WALLET_ADAPTER_NOT_SUPPORTEDServer-side wallet provisioning not supported for BYO custody appsProvision wallets via your adapter
SDK_WALLET_REQUIRED (409)The user has no wallet yet (app with on-demand or no wallet creation)Call createWallet(), or hide the feature. See Wallet Creation
SDK_WALLET_PROVISIONING_DISABLED (403)The app's wallet creation is set to NeverChange it in the dashboard, or do not offer wallet features
SDK_WALLET_PROVISIONING_UNSUPPORTED (409)The user signed in with their own wallet or a passkey; there is no wallet to createUse the wallet the user signed in with

Co-signed wallets

Apps in co-signed custody (see Co-signed Wallets). A signing call that needs the user's vote is not an error: it answers 202 SDK_COSIGN_PENDING and the SDK reports status: 'cosign_pending'.

CodeDescriptionResolution
SDK_UPGRADE_REQUIRED (409)The app creates co-signed wallets and this SDK did not send the device keyUpgrade @pollar/core to 0.11.5 or later
SDK_COSIGN_NOT_CONFIGURED (503)Co-signing is not available on the app's networkContact Pollar
SDK_COSIGN_REQUEST_NOT_FOUND (404)No request with that id or fingerprint belongs to this userRefresh pollar.cosign.pending()
SDK_COSIGN_REQUEST_NOT_PENDING (409)The request already reached a final state (approved, rejected, expired)Read it with ?sync=1 to see the outcome
SDK_COSIGN_DEVICE_NOT_ENROLLED (403)The key that stamped the vote is not one of the user's devicesSign in on the device that created the wallet, or enroll this one from it
SDK_COSIGN_UPSTREAM_ERROR (502)Turnkey or the co-signing service refused or failedRetry; the request stays pending until its 24 hour window closes
SDK_COSIGN_USER_REQUIRED (409)A server-side call tried to sign for a co-signed wallet; only the user's device can voteRun the operation from the SDK
SDK_COSIGN_VERIFICATION_FAILEDSDK only: the payload Turnkey holds differs from the one shown; the device rejected the requestReport it to Pollar with the verification report
SDK_CONFIRMATION_DECLINEDSDK only: the user declined the prompt shown under confirmation: 'prompt'Nothing was signed; the user can retry
SDK_CONFIRMATION_UNAVAILABLESDK only: confirmation: 'prompt' with nothing rendering the promptMount PollarProvider or subscribe with onConfirmationRequest

Trustlines

CodeDescriptionResolution
TRUSTLINE_FAILEDFailed to create/remove a trustline on StellarRetry — transient network issue
INSUFFICIENT_FUNDS_FOR_TRUSTLINENot enough XLM to cover the trustline reserve (0.5 XLM)Top up the funding wallet
TRUSTLINE_HAS_BALANCECannot remove a trustline that still holds a balanceMove the balance to zero first
NO_DEFAULT_TRUSTLINESNo default assets are configured for the appConfigure assets under Wallets → Tokens & Trustlines

Signer rotation

CodeDescriptionResolution
SIGNER_ROTATION_NOT_ENABLED (403)The app does not sponsor signer rotationsTurn on Sponsor signer rotations and Include external wallets under Wallets > Sponsorship
SIGNER_ROTATION_NOT_GRANTED (403)The user holds no unspent rotation grant, or already used itGrant one from Users > Accounts or with POST /v3/wallets/{publicKey}/signer-rotation
SIGNER_ROTATION_PENDING (409)A sponsored rotation built for this user can still be submittedSubmit it, or wait until its expiresAt passes
SIGNER_ROTATION_INVALID (422)The wallet is custodial or not created yet, or the requested change is not allowedRead details; see the rotation rules

Transactions

CodeDescriptionResolution
SDK_TX_BUILD_ERRORThe transaction could not be builtCheck operation params (destination, amount, asset)
TX_UNSUPPORTED_OPERATIONOperation type is not supportedUse a supported operation (e.g. payment)
TX_INVALID_SIGNED_XDRThe signed XDR is malformedRe-sign from the built XDR
TX_SIGN_FAILEDSigning failedRetry; for external wallets, re-approve in the wallet
TX_SUBMIT_FAILEDStellar rejected the transactionInspect resultCode on the outcome
TX_IDEMPOTENCY_CONFLICTA conflicting submission is already in flightWait and check transaction status

Soroban auth entries

Returned by POST /tx/sign-auth-entry (pollar.signAuthEntry()) when the app's allowlist refuses to authorize an entry, and by the dashboard/Server API when a row is saved. Configured under Wallets → Auth Policy.

Every denial here also carries applicationId and applicationName — the app the decision was made against, which is the app your API key resolves to, not necessarily the one open in the dashboard.

{
  "code": "SOROBAN_AUTH_NO_POLICY",
  "success": false,
  "message": "no Soroban auth-entry allowlist is configured for this application",
  "applicationId": "cm…",
  "applicationName": "Acme Checkout"
}
CodeDescriptionFix
SOROBAN_AUTH_NO_POLICYThe app has no enabled allowlist rowsAdd a row — or check applicationName against the app you configured
SOROBAN_AUTH_CONTRACT_NOT_ALLOWEDA contract in the invocation tree is not allowlistedAdd it; sub-invocations each need their own row
SOROBAN_AUTH_FUNCTION_NOT_ALLOWEDThe contract is allowlisted, the invoked function is notNames match exactly: Transfer is not transfer
SOROBAN_AUTH_ADDRESS_MISMATCHThe entry authorizes an address other than the caller's walletBuild the entry for the session's own address
SOROBAN_AUTH_ENTRY_INVALIDNot a valid SorobanAuthorizationEntry, or not address-credentialsSend the entry itself — a HashIDPreimage is a different type
SOROBAN_AUTH_EXPIRATION_TOO_LONGvalidUntilLedger is in the past or beyond the app's windowRecompute from the latest ledger; the ceiling is 300 ledgers
SOROBAN_AUTH_SIGN_FAILEDThe entry passed the allowlist but signing failedRetry — this one is on Pollar's side

Saving an allowlist row (dashboard or Server API) can also answer:

CodeDescription
CONTRACT_FUNCTION_UNKNOWNThe row names a function the contract does not expose. message names which
CONTRACT_NOT_FOUNDThe contract is not deployed on this app's network
CONTRACT_INTROSPECTION_FAILEDPollar could not read the contract (RPC unreachable)
SOROBAN_AUTH_WILDCARD_REQUIRES_ANY_FUNCTIONThe "any contract" row may only carry the "any function" wildcard

Distribution

CodeDescriptionResolution
DISTRIBUTION_RULE_NOT_FOUNDThe distribution rule does not existVerify the rule id
DISTRIBUTION_ASSET_NOT_ENABLEDThe asset is not enabled for distributionEnable it under Treasury → Token Distribution
DISTRIBUTION_RULE_DISABLEDThe rule is disabledEnable the rule
DISTRIBUTION_RULE_EXPIREDThe rule's validity window has ended—
DISTRIBUTION_RULE_EXHAUSTEDThe rule's total allocation is used up—
DISTRIBUTION_RATE_LIMIT_EXCEEDEDThe user exceeded the rule's claim rate limitConfigured per rule in Treasury → Token Distribution
DISTRIBUTION_NO_DISTRIBUTION_WALLETNo distribution wallet is configuredConfigure one under Treasury → Token Distribution

KYC & Ramps

CodeDescription
SDK_KYC_PROVIDER_NOT_FOUNDKYC provider not found
SDK_KYC_PROVIDER_NOT_ENABLEDKYC provider not enabled for the app
SDK_KYC_SESSION_EXPIREDKYC session expired
SDK_KYC_VERIFICATION_NOT_FOUNDKYC verification not found
SDK_RAMPS_PROVIDER_NOT_FOUNDRamp provider not found
SDK_RAMPS_QUOTE_NOT_FOUNDRamp quote not found
SDK_RAMPS_QUOTE_EXPIREDRamp quote expired — request a new one
SDK_RAMPS_TX_NOT_FOUNDRamp transaction not found
SDK_RAMPS_ASSET_NOT_ENABLEDThe ramp asset is not enabled for the app
SDK_RAMPS_AMOUNT_OUT_OF_RANGEAmount outside the route's min/max — the bounds come back as limit, limitAmount and limitCurrency
SDK_RAMPS_INSUFFICIENT_BALANCEThe wallet does not hold enough to cover the off-ramp. Checked before anything is submitted, so the balance is untouched
SDK_RAMPS_WALLET_UNSUPPORTEDThe wallet cannot drive this ramp (e.g. a passkey smart account)
SDK_RAMPS_KYC_REQUIREDThe provider needs KYC first — send the user to kycUrl
SDK_RAMPS_PROVIDER_NOT_CONFIGUREDThe ramp provider has no usable credentials for this app
SDK_RAMPS_ONCHAIN_SUBMIT_FAILEDThe network rejected the on-chain leg, so nothing moved. details carries the Stellar result code — txInsufficientBalance means the wallet has no XLM for the fee and the app does not sponsor this asset
SDK_RAMPS_ANCHOR_ERROR / SDK_RAMPS_BRIDGE_ERROR / SDK_RAMPS_ETHERFUSE_ERRORThe provider failed upstream — retry in a moment
SDK_RAMPS_BRIDGE_TESTNET_NOT_SETTLEABLEThe route settles on mainnet only; on testnet it stops at the deposit instructions

Session, DPoP & passkeys

End-user session and token errors (sdk-api). These are handled by the SDK's auth flow; surface to users as "please sign in again".

CodeDescription
SDK_AUTH_INVALID_TOKEN / SDK_AUTH_TOKEN_EXPIREDAccess token invalid or expired
SDK_AUTH_DPOP_REQUIRED / SDK_AUTH_DPOP_INVALID / SDK_AUTH_DPOP_USE_NONCEDPoP proof required / invalid / needs nonce
SDK_REFRESH_TOKEN_INVALID / _EXPIRED / _REUSEDRefresh token invalid, expired, or reused
PASSKEY_CHALLENGE_MISSING / PASSKEY_VERIFICATION_FAILED / PASSKEY_DEPLOY_FAILEDPasskey ceremony errors

This is not the full enum — the server defines additional internal codes (hub-api admin, Pollar Pay, authentik, wallet-adapter). The codes above are the ones an SDK or Server API integrator is most likely to encounter.


Handling errors in the SDK

import { PollarFlowError } from '@pollar/core';

// Operational failures come back as outcomes — no try/catch needed.
const result = await pollar.runTx('payment', { destination, amount, asset });
if (result.status === 'error') {
  switch (result.resultCode) {
    case 'tx_insufficient_balance':
      // not enough of the asset
      break;
    default:
      console.error(result.details);
  }
}

// Misuse of the flow API throws.
try {
  pollar.sendEmailCode('[email protected]');
} catch (err) {
  if (err instanceof PollarFlowError) {
    // wrong step for the current AuthState
  }
}

To observe transaction failures reactively, subscribe to onTransactionStateChange and inspect state.phase / state.details when state.step === 'error'.

On this page

Was this helpful?